Chapter9 Part2
Chapter9 Part2
Chapter9 Part2
Sorting:
Shell Sort and Heap Sort
Intuitive Sorting Algorithms are Slow
Why are the intuitive sorting algorithms so slow?
Always involves a nested loop, bringing complexity up to O(n2)
Can we alleviate this quadratic bane?
Let’s look at an example
6 7 2 1 5 8 3 4
This array contains 8 elements
If sorting has O(n2) complexity, then t(n) = n2, and t(8) = 64
What if we split the array in two halves?
6 7 2 1 5 8 3 4
Using the same algorithm to sort the halves separately
For each half of the array, t(4) = 16
Therefore, for the entire array, t(4) x 2 = 32
Much less time complex than sorting the whole array!
Efficient sorting
However… sorting each half does not sort the entire array!
But it does bring the array closer to a fully sorted array
Arrays can be subdivided in many ways – not just halved
Let’s consider comb sort again
Compare elements that are m places apart
Value of m is called a gap
The gap shrinks non-linearly for each pass through the array
In each pass we bubble sort only a subset of elements
44 45 46 48 43 12
Sorted Unsorted
Insertion sort removes elements from unsorted, inserting them into the correct
location in sorted
Selection sort swaps the smallest element in unsorted with the element at the
head of unsorted, moving it into sorted
The shell sort algorithm
Uses comb sort’s idea: Use a variable gap to create sub-arrays
Sort sub-arrays using any algorithm, decrease gap, until sorted
Shell Sort
Let’s look at an example
n=6
Choose an initial gap = 3
Find sub-arrays
3 6 2 8 1 5
Apply a sorting algorithm
to every sub-array
Use any sorting algorithm
Insertion sort is very commonly
used, so we’ll do the same
for this example 3 8
Shrink the gap until gap = 1
6 1
2 5
3 1 2 8 6 5
Shell Sort
Moving on to the second pass
We’ll reduce the gap by 1
for this example
gap = 2
Find sub-arrays 3 1 2 8 6 5
Apply insertion sort to
sub-arrays
3 2 6
Now for the final pass 1 8 5
gap = 1
We’re now working with
the full array
Apply insertion sort 2 1 3 5 6 8
Last nonleaf
4 7 7
7 4 4 4 6 4
6 5 3 6 5 3 4 5 3
4 7 4 6 5 3 7 4 4 6 5 3 7 6 4 4 5 3
Heap Sort
Phase 2: The sorting procedure
for i = data.length-1 down to 2
swap the root with the element in position i;
p = the root;
while p is not a leaf and p < any of its children
swap p with the larger child;
Dequeuing algorithm
Swap largest element (always at data[0]) with last leaf (at data[i])
Both are efficient to work with, due to direct access
Restore the heap property
Set p to the root of the heap
While p is less than any of its children, swap p with its largest child
Efficiency is O(lg n)
Heap Sort
Phase 2: The sorting procedure
7 3 6 6
6 4 6 4 3 4 5 4
4 5 3 4 5 7 4 5 4 3
7 6 4 4 5 3 3 6 4 4 5 7 6 3 4 4 5 7 6 5 4 4 3 7
3 5 5 3
5 4 3 4 4 4 4 4
4 6 4 3 5
3 5 4 4 6 7 5 3 4 4 6 7 5 4 4 3 6 7 3 4 4 5 6 7
Heap Sort
3 4 4 4 3
4 4 3 4 3 4 3 4
5
3 4 4 5 6 7 4 3 4 5 6 7 4 3 4 5 6 7 4 3 4 5 6 7 3 4 4 5 6 7
Heap Sort
Efficiency of heap sort?
O(n)
heapsort(data[])
transform data[] into a heap; // Floyd’s heapifying algorithm
for i = data.length-1 down to 2 O(n)
swap the root with the element in position i;
restore the heap property for the tree data[0], …, data[i-1];