Data Structures & Algorithms
© John Urrutia 2016, All Rights Reserved
Advanced Sorting
The Shell Sort
Created by Donald Shell
Assuming a random distribution of keys try to
position this key reasonably close to its correct
position by sorting elements across widely
disbursed intervals.
Trade off between the number of swaps vs
number of comparisons.
Each pass through the data will reduce the
width of the of the interval
The Shell Sort (cont.)
The last pass will have an interval of 1 which
will do a standard insertion sort.
Very easy to code
Difficult to select an appropriate interval to
provide efficiency.
The Shell Sort
Big ‘O’ ranges from:
N2 – Normal insertion sort
N7/6 – Best Efficiency for Shell Sort
Example
13 items to sort
Insertion Sort
Max Copies for insertion = 67
Max Comparisons = 55
Shell Sort
Max Copies for insertion = 67
Max Comparisons = 55
Gap
Sequence
5
3
1
Original
81
94
11
96
12
35
17
95
28
58
41
75
15
Before
81
94
11
96
12
35
17
95
28
58
41
75
15
(1,6,11)
35
41
81
(2,7,12)
17
75
94
(3,8,13)
11
15
95
(4,9)
28
96
(5,10)
12
58
After
35
17
11
28
12
41
75
15
96
58
81
94
95
Before
35
17
11
28
12
41
75
15
96
58
81
94
95
(1,4,7,10,13)
28
35
58
75
95
(2,5,8,11)
12
15
17
81
(3,6,9,12)
11
41
94
96
After
28
12
11
35
15
41
58
17
94
75
81
96
95
Before
28
12
11
35
15
41
58
17
94
75
81
96
95
After
11
12
15
17
28
35
41
58
75
81
94
95
96
Shell Sort Code
Step 1 – Find an interval for the array
void shellSort()
{
int inner, outer;
long temp;
int h = 1;
while (h <= nElems / 3)
h = h * 3 + 1
Creates the following sequence (1, 4, 13, 40,
121,…)
Shell Sort Code
Step 2 – insertion sort by interval
while (h > 0)
{for (outer = h; outer < nElems; outer++)
{temp = theArray[outer];
inner = outer;
while (inner > h-1 && theArray[inner-h] >= temp)
{
theArray[inner] = theArray[inner-h];
inner-=h;
}
theArray[inner] = temp;
}
h=(h-1)/3;
}
The QuickSort
One of the most popular advanced sorting
methods
Created by C. A. R. Hoare in 1962
Uses a Divide and Conquer approach
Partitions the data then subdivides the
partitions using recursion
Perhaps the fastest O(N * log2 N2) for random
data sorted in-place
Degenerates to O(N2) for data that is already in
order
The QuickSort
The algorithm
Select a “pivot” value to use for partitioning the
data
Create the Partitions
Place all values less than the pivot in the left
partition
Place all values Greater than the pivot in the right
partition
Return the position of the partition boundary
Call Recursive with the sub-partitions.
The QuickSort
Un-partitioned Array
6
3
1
2
94
2
7
78
Partitioned Array
3
50
3
6
Pivot--
8
9
Sorted
42
The QuickSort
Left Partition
has 3
elements
(insertion
Left Partition
sort)
has 2
elements
(insertion
sort)
42
3
3
3
3
3
3
3
3
3
3
89
89
27
27
27
27
12
12
12
12
12
63
63
63
12
12
12
27
27
27
27
27
12 94 27
12 94 27
12 94 89
63 94 89
36 94 89
36 94 89
36 50 89
36 50 42
36 50 42
3642 50
3642 50
78 3
78 42
78 42
78 42
78 42
78 42
78 42
78 89
63 89
63 89
6378
5036 pivot
50 36
50 36
50 36
50 63 pivot
5063 Right Partition
9463 has 6 elements
(QuickSort)
9463
94 78 pivot
9478 Right Partition
has 3 elements
89 94 (insertion
sort)
The QuickSort
The
void recQuickSort(int left, int right)
Recursive Code
{ if (right - left <= 0) // if size <= 1,
return; // already sorted
else // size is 2 or large
r
{
long pivot = theArray[right]; // rightmost item
// partition range
int partition = partitionIt(left, right, pivot);
recQuickSort(left, partition - 1); // sort left side
recQuickSort(partition + 1, right); // sort right side
}
}
The
QuickSort
The Partitioning Code
int partitionIt(int left, int right, long pivot)
{
int leftPtr = left - 1;// left (after ++)
int rightPtr = right; // right-1 (after --)
while (true)
{
while (theArray[++leftPtr] < pivot) ; // find bigger
item
while (rightPtr > 0 &&
theArray[--rightPtr] > pivot) ; // find smaller item
The QuickSort
The Partitioning Code (continued)
if (leftPtr >= rightPtr) // if pointers cross,
break; // partition done
else // not crossed, so
swap(leftPtr, rightPtr); // swap elements
} // end while(true)
swap(leftPtr, right); // restore pivot
return leftPtr; // return pivot location
} // end partitionIt()
The QuickSort
Finding a good pivot value
Median-Of-Three
Sorts the Three elements at the beginning,
ending & center into their correct partitions
and uses the center as the pivot.
Avoids O(N2)
Slightly improves number of items that must
be partitioned
Increases the speed of the inner partitioning
loop
The Radix Sort
Implementation of a radix sort using Queues
Radix sort passes once for each digit in
the input
At the conclusion of each pass the digit is
in order
ie.
radix sort of two digit numbers
91, 46, 85, 15, 92, 35, 31, 22
Queue application – sort of
first pass orders by the one’s digit
Before 91, 46, 85, 15, 92, 35, 31, 22
After 91, 31, 22, 92, 85, 15, 35, 46
second pass orders by the ten’s digit
Before 91, 31, 22, 92, 85, 15, 35, 46
After 15, 22, 31, 35, 46, 85, 91, 92
Queues in order
Pass 1 -9
1
,4
6
8
,
5
1
,
5
9,
2
3,
5
3, 2 ,
2
1
Bin Bin Bin Bin Bin Bin Bin Bin Bin Bin
0
1
2
3
4
5
6
7
8
9
Pass 1 -
,
,
,
,
,
,
,
Queues in order
9
1
Pass 2 -
3
,
1
9
,
2
2
,
2
4
,
6
8
,
5
1
,
5
3
,
5
Bin Bin Bin Bin Bin Bin Bin Bin Bin Bin
0
1
2
3
4
5
6
7
8
9
Pass 2 -
,
,
,
,
,
,
,
Radix Sort
The Code:
Pass 1 – One’s digit
Each element is enqueued onto the correct queue
and counted
Pass 2 – Ten’s digit
Each queue is dequeued into a temp array & reenqueued in the correct order
Each queue is dequeued to the console