Chapter 6 - Advanced Sorting Algorithms
Chapter 6 - Advanced Sorting Algorithms
Algorithms
This chapter covers:
Shell Sort
Heap Sort
Quick Sort
Merge Sort
1
Shell Sort
The shell sort, also known as the diminishing
increment sort, was developed by Donald L. Shell
in 1959.
The idea behind shell sort is that it is faster to
sort an array if parts of it are already sorted.
The original array is first divided into a number
of smaller subarrays, these subarrays are sorted,
and then they are combined into the overall array
and this is sorted.
5
In the above example:
6
In the above example, we used three
iterations: a 5-sort, a 3-sort and a 1-sort.
This sequence is known as the diminishing
increment. But how do we decide on this
sequence of increments?
Unfortunately, there is no definitive answer
to this question. In the original algorithm
proposed by Donald L. Shell, powers of 2
were used for the increments, e.g. 16, 8, 4, 2,
1.
However, this is not the most efficient
technique. Experimental studies have shown
that increments calculated according to the
following conditions lead to better efficiency:
h1 = 1
hi+1 = 3hi + 1
For example, for a list of length 10,000 the
sequence of increments would 7 be 3280,
1093, 364, 121, 40, 13, 4, 1.
Another decision that must be made with shell
sort is what sorting algorithms should be used
to sort the subarrays at each iteration?
A number of different choices have been made:
for example, one technique is to use insertion
sort for every iteration and bubble sort for the
last iteration.
Actually, whatever simple sorting algorithms
are used for the different iterations, shell sort
performs better than the simple sorting
algorithms on their own.
It may seem that shell sort should be less
efficient, since it performs a number of
different sorts, but remember that most of
these sorts are on small arrays, and in most
cases the data is already almost sorted.
An experimental analysis has shown that the
complexity of shell sort is approximately
O(n1.25), which is better than the O(n2) offered
by the simple algorithms. 8
Example2:
sort: (5, 8, 2, 4, 1, 3, 9, 7, 6, 0)
Solution:
4 – sort
Sort(5, 1, 6) – 1, 8, 2, 4, 5, 3, 9, 7, 6 , 0
Sort(8, 3, 0) – 1, 0, 2, 4, 5, 3, 9, 7, 6, 8
Sort(2, 9) – 1, 0, 2, 4, 5, 3, 9, 7, 6, 8
Sort(4,7) - 1, 0, 2, 4, 5, 3, 9, 7, 6, 8
1- sort
Sort(1, 0, 2, 4, 5, 3, 9, 7, 6, 8) – 0,1, 2, 3,
4, 5, 6, 7,8,9 9
Heap Sort
Heap is a binary tree that has two
properties:
The value of each node is greater than or equal to
the values stored in each of its children.
The tree is perfectly balanced, and the leaves in
the last level are all in the leftmost positions.
(filled from left to right)
A property of the heap data structure is that
the largest element is always at the root of
the tree.
A common way of implementing a heap is to
use an array
10
Heap Sort…
The heap sort works by first rearranging the
input array so that it is a heap, and then
removing the largest elements from the
heap one by one. Pseudocode for the heap
sort is given below:
HeapSort(data):
Transform data into a heap
for (i = n-1; i > 1; i--)
11
Example
12
Quick Sort
Quicksort was developed by C. A. R. Hoare in
1961, and is probably the most famous and
widely used of sorting algorithms.
The guiding principle behind the algorithm
is similar to that of shell sort: it is more
efficient to sort a number of smaller
subarrays than to sort one big array
13
The Algorithm
In quicksort the original array is first divided
into two subarrays, the first of which contains
only elements that are less than or equal to a
chosen element, called the bound or pivot.
The second subarray contains elements that
are greater than or equal to the bound. If
each of these subarrays is sorted separately
they can be combined into a final sorted array.
To sort each of the subarrays, they are both
subdivided again using two new bounds,
making a total of 4 subarrays.
The partitioning is repeated again for each of
these subarrays, and so on until the subarrays
consist of a single element each, and do not
need to be sorted 14
…
Quicksort is inherently recursive in nature,
since it consists of the same simple
operation (the partitioning) applied to
successively smaller subarrays.
Pseudocode for quicksort is given below:
15
…
The pivot element can be selected in many
ways. We may select the first element as a
pivot [see the demo], or we may select the
middle element of the array or may be a
randomly selected pivot [bound] element
can be used. The following example
demonstrates a pivot element selected
from the middle of the data. In the
average, quicksort has complexity of
nlogn.
16
Example [ pivot selected from
the middle]
17
In the above Example
To begin with, the middle element 6 is chosen as
the bound, and the array partitioned into two
subarrays.
Each of these subarrays is then partitioned
using the bounds 2 and 10 respectively.
In the third phase, two of the four subarrays
only have one element, so they are not
partitioned further.
The other two subarrays are partitioned once
more, using the bounds 3 and 7.
Finally we are left with only subarrays consisting
of a single element. At this point, the subarrays
and bounds are recombined successively,
resulting in the sorted array. 18
Merge Sort
Mergesort also works by successively
partitioning the array into two subarrays,
but it guarantees that the subarrays are of
approximately equal size.
This is possible because in mergesort the
array is partitioned without regard to the
values of their elements: it is simply divided
down the middle into two halves.
Each of these halves is recursively sorted
using the same algorithm.
After the two subarrays have been sorted,
they are merged back together again.
The recursion continues until the subarrays
consist of a single element, in which case
they are already sorted. 19
Pseudocode code for merge
sort
20
Example
21