17
1 CSCD 300 Data Structures Donald Shell’s Sorting Algorithm Originally developed by Bill Clark, modified by Tom Capaul and Tim Rolfe

Shell Sort

Embed Size (px)

Citation preview

Page 1: Shell Sort

1

CSCD 300 Data StructuresDonald Shell’s Sorting Algorithm

Originally developed by Bill Clark, modified by Tom Capaul and Tim Rolfe

Page 2: Shell Sort

2

Shell Sort - Introduction

More properly, Shell’s SortCreated in 1959 by Donald ShellLink 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.

Page 3: Shell Sort

3

Shell Sort -General Description

Essentially a segmented insertion sortDivides 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.

Page 4: Shell Sort

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.

Page 5: Shell Sort

5

Shell Sort - example

80 93 60 6812 8542 30 10

Initial Segmenting Gap = 4

10 30 60 6812 8542 93 80

Page 6: Shell Sort

6

Shell Sort - example (2)

10 30 60 6812 8542 93 80

Resegmenting Gap = 2

10 12 42 6830 9360 85 80

Page 7: Shell Sort

7

Shell Sort - example (3)

10 12 30 8042 8560 68 93

10 12 42 6830 9360 85 80

Resegmenting Gap = 1

Page 8: Shell Sort

8

Gap Sequences for Shell Sort

The sequence h1, h2, h3,. . . , ht 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 h1 = 1.For any gap value hk we have A[i] <= A[i + hk]An array A for which this is true is hk sorted.An array which is hk sorted and is then hk-1 sorted remains hk sorted.

Page 9: Shell Sort

9

Shell Sort - Ideal Gap Sequence

Although any increasing sequence will work ( if h1 = 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.

Page 10: Shell Sort

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.

Page 11: Shell Sort

11

Shell Sort - Added Gap Sequence

Donald Knuth, in his discussion of Shell’s Sort, recommended another sequence of gaps.h0 = 1hj+1 = hj * 3 + 1Find the hj > n, then start with hj/3

Page 12: Shell Sort

12

Link to the Java program that generated the above data.

Page 13: Shell Sort

13

Shell Sort - Time Complexity

Time complexity: O(nr) with 1 < r < 2This is better than O(n2) but generally worse than O(n log2n).

Page 14: Shell Sort

14

Shellsort - Code

public static voidshellSort( 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; }}

Page 15: Shell Sort

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; }

80 93 60 6812 8542 30 10

[0] [1] [2] [3] [4] [5] [6] [7] [8]

n: 9gap: 4

i:j:

theArray

Page 16: Shell Sort

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: 9gap: 2

i:j:

theArray 10 30 60 6812 8542 93 80

Page 17: Shell Sort

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: 9gap: 1

i:j:

theArray 10 12 42 6830 9360 85 80