1
CSCD 300 Data Structures
Donald Shell’s Sorting Algorithm
Originally developed by Bill Clark, modified
by Tom Capaul and Tim Rolfe
2
Shell Sort - Introduction
More properly, Shell’s Sort
Created in 1959 by Donald Shell
Link to a local copy of the article:
Donald Shell, “A High-Speed Sorting
Procedure”, Communications of the ACM
Vol 2, No. 7 (July 1959), 30-32
Originally Shell built his idea on top of
Bubble Sort (link to article flowchart),
but it has since been transported over to
Insertion Sort.
3
Shell Sort -General Description
Essentially a segmented insertion sort
Divides an array into several smaller non-
contiguous segments
The distance between successive elements
in one segment is called a gap.
Each segment is sorted within itself using
insertion sort.
Then resegment into larger segments
(smaller gaps) and repeat sort.
Continue until only one segment (gap = 1) -
final sort finishes array sorting.
4
Shell Sort -Background
General Theory:
Makes use of the intrinsic strengths of Insertion
sort. Insertion sort is fastest when:
The array is nearly sorted.
The array contains only a small number of
data items.
Shell sort works well because:
It always deals with a small number of elements.
Elements are moved a long way through array
with each swap and this leaves it more nearly
sorted.
5
Shell Sort - example
809360 6812 854230 10
Initial Segmenting Gap = 4
103060 6812 854293 80
6
Shell Sort - example (2)
103060 6812 854293 80
Resegmenting Gap = 2
101242 6830 936085 80
7
Shell Sort - example (3)
101230 8042 856068 93
101242 6830 936085 80
Resegmenting Gap = 1
8
Gap Sequences for Shell Sort
The sequence h
1
, h
2
, h
3
,. . . , h
t
is a sequence of
increasing integer values which will be used as
a sequence (from right to left) of gap values.
Any sequence will work as long as it is increasing
and h
1
= 1.
For any gap value h
k
we have A[i] <= A[i + h
k
]
An array A for which this is true is h
k
sorted.
An array which is h
k
sorted and is then h
k-1
sorted remains h
k
sorted.
9
Shell Sort - Ideal Gap Sequence
Although any increasing sequence will
work ( if h
1
= 1):
Best results are obtained when all values in
the gap sequence are relatively prime
(sequence does not share any divisors).
Obtaining a relatively prime sequence is often
not practical in a program so practical
solutions try to approximate relatively prime
sequences.
10
Shell Sort - Practical Gap Sequences
Three possibilities presented:
1) Shell's suggestion - first gap is N/2 - successive
gaps are previous value divided by 2.
Odd gaps only - like Shell method except if division
produces an even number add 1.
better performance than 1) since all odd values
eliminates the factor 2.
2.2 method - like Odd gaps method (add 1 to even
division result) but use a divisor of 2.2 and
truncate.
best performance of all - most nearly a relatively
prime sequence.
11
Shell Sort - Added Gap Sequence
Donald Knuth, in his discussion of Shell’s
Sort, recommended another sequence of
gaps.
h
0 = 1
h
j+1
= h
j
* 3 + 1
Find the h
j
> n, then start with h
j
/3
12
Link to the Java program that generated the above data.
13
Shell Sort - Time Complexity
Time complexity: O(n
r
) with 1 < r < 2
This is better than O(n
2
) but generally
worse than O(n log
2
n).
14
Shellsort - Code
public static void
shellSort( Comparable[ ] theArray, int n ) {
// shellSort: sort first n items in array theArray
for( int gap = n / 2; gap > 0; gap = gap / 2 )
for( int i = gap; i < n; i++ ) {
Comparable tmp = theArray[ i ];
int j = i;
for( ; j >= gap && tmp.compareTo(theArray[ j - gap ]) < 0 ; j -= gap )
theArray[ j ] = theArray[ j - gap ];
theArray[ j ] = tmp;
}
}
15
ShellSort -Trace (gap = 4)
for( int gap = n / 2; gap > 0; gap = gap / 2 )
for( int i = gap; i < n; i++ ) {
Comparable tmp = theArray[ i ];
int j = i;
for( ; j >= gap && tmp.compareTo(theArray[ j - gap ]) < 0 ; j -= gap )
theArray[ j ] = theArray[ j - gap ];
theArray[ j ] = tmp;
}
809360 6812 854230 10
[0] [1] [2] [3] [4] [5] [6] [7] [8]
n: 9
gap: 4
i:
j:
theArray
16
ShellSort -Trace (gap = 2)
for( int gap = n / 2; gap > 0; gap = gap / 2 )
for( int i = gap; i < n; i++ ) {
Comparable tmp = theArray[ i ];
int j = i;
for( ; j >= gap && tmp.compareTo(theArray[ j - gap ]) < 0 ; j -= gap )
theArray[ j ] = theArray[ j - gap ];
theArray[ j ] = tmp;
}
[0] [1] [2] [3] [4] [5] [6] [7] [8]
n: 9
gap: 2
i:
j:
theArray103060 6812 854293 80
17
ShellSort -Trace (gap = 1)
for( int gap = n / 2; gap > 0; gap = gap / 2 )
for( int i = gap; i < n; i++ ) {
Comparable tmp = theArray[ i ];
int j = i;
for( ; j >= gap && tmp.compareTo(theArray[ j - gap ]) < 0 ; j -= gap )
theArray[ j ] = theArray[ j - gap ];
theArray[ j ] = tmp;
}
[0] [1] [2] [3] [4] [5] [6] [7] [8]
n: 9
gap: 1
i:
j:
theArray101242 6830 936085 80