This method can be thought of as an improvement over bubblesort, although we will describe it in full detail. During a bubblesort, the small (resp. large) values get pushed towards the beginning (resp. end) of the array, but the method is too slow because items still only get to move one spot at a time. The shellsort method will instead start by allowing exchanges which jump over rather large distances. Following this, the method will check over slighly smaller distances, and then smaller distances, until eventually it checks each element against its immediate neighbors.
The method for h-sorting an array is relatively simple. Make a pass through the array from beginning to end, and at each spot check whether the array element is truly less than the element which is h-spaces farther in the array. If this is not true, then swap those two elements and then continue making your pass through the array until you reach the end (actually, until you are less than h spaces away from the end).
If you complete the entire pass without ever swapping an element, then the array must indeed be correctly h-sorted and you are done with the h-sort. However if one or more swaps take place, you must make another pass through the entire array. Again, if no swaps are made during this new pass, the h-sort is done, but otherwise you must again make another pass. Eventually, there will come a time when the file is h-sorted and this process ends.
So this is how you h-sort a file. Notice that if you 1-sort a file, you have guaranteed that every value is less than the value to its right, and so the entire array will be sorted. For other values of h, an h-sorted file will not be perfectly sorted, but it turns out to be useful to do these h-sorts anyway.
The overall shellsort is the following. A sequence of decreasing h-values is chosen, and h-sort is called for each of these values, ending with h=1 (thus perfectly sorting the file by the time we are done).
Note: The magic sequence of h-values chosen is unimportant for the assignment. Various sequences have been studied by computer scientists and we have chosen a relatively decent such sequence and written the code for this sequence.
There are three files to download:
www.cs.luc.edu/~mhg/comp125/homework/shellsort.frm
www.cs.luc.edu/~mhg/comp125/homework/shellsort.frx
www.cs.luc.edu/~mhg/comp125/homework/shellsort.vbp
All you need to know is the following:
The data is stored in a global array which was created with a line
such as
Dim TheArray(1 to arraysize) As Single
where arraysize is also a global variable. The actual data
consists of floating point numbers between 0 and 1 which are chosen at
random.
The function which you must write is at the bottom of the code, and is
declared as:
Private Sub hsort(h As Long)
End Sub
Some specific suggestions:
A(1) | A(2) | A(3) | A(4) | A(5) | A(6) | A(7) | A(8) | A(9) | A(10) |
---|---|---|---|---|---|---|---|---|---|
0.334 | 0.068 | 0.594 | 0.766 | 0.189 | 0.537 | 0.327 | 0.394 | 0.073 | 0.832 |
Shellsort first attempts to 4-sort the file. During the first pass of the 4-sort, it exchanges the pairs, A(1):A(5) then A(3):A(7) then A(4):A(8) then A(5):A(9). Since exchanges took place, it makes a second pass while 4-sorting, causing the exchanges A(1):A(5) but no others. This necessitates a third pass during which no exchanges end up taking place and thus the file is correctly 4-sorted at this point. The 4-sort is animated as follows:
A(1) | A(2) | A(3) | A(4) | A(5) | A(6) | A(7) | A(8) | A(9) | A(10) |
---|---|---|---|---|---|---|---|---|---|
0.334 | 0.068 | 0.594 | 0.766 | 0.189 | 0.537 | 0.327 | 0.394 | 0.073 | 0.832 |
0.189 | 0.068 | 0.594 | 0.766 | 0.334 | 0.537 | 0.327 | 0.394 | 0.073 | 0.832 |
0.189 | 0.068 | 0.327 | 0.766 | 0.334 | 0.537 | 0.594 | 0.394 | 0.073 | 0.832 |
0.189 | 0.068 | 0.327 | 0.394 | 0.334 | 0.537 | 0.594 | 0.766 | 0.073 | 0.832 |
0.189 | 0.068 | 0.327 | 0.394 | 0.073 | 0.537 | 0.594 | 0.766 | 0.334 | 0.832 |
0.073 | 0.068 | 0.327 | 0.394 | 0.189 | 0.537 | 0.594 | 0.766 | 0.334 | 0.832 |
After this point, the overall shellsort algorithm now calls for a 1-sort which causes swaps A(1):A(2), A(4):A(5), A(8):A(9) during the first pass; A(3):A(4) and A(7):A(8) during the second pass; A(6):A(7) during the third pass; A(5):A(6) during the fourth pass; and no exchanges during the fifth pass, thereby ending the 1-sort.
A(1) | A(2) | A(3) | A(4) | A(5) | A(6) | A(7) | A(8) | A(9) | A(10) |
---|---|---|---|---|---|---|---|---|---|
0.073 | 0.068 | 0.327 | 0.394 | 0.189 | 0.537 | 0.594 | 0.766 | 0.334 | 0.832 |
0.068 | 0.073 | 0.327 | 0.394 | 0.189 | 0.537 | 0.594 | 0.766 | 0.334 | 0.832 |
0.068 | 0.073 | 0.327 | 0.189 | 0.394 | 0.537 | 0.594 | 0.766 | 0.334 | 0.832 |
0.068 | 0.073 | 0.327 | 0.189 | 0.394 | 0.537 | 0.594 | 0.334 | 0.766 | 0.832 |
0.068 | 0.073 | 0.189 | 0.327 | 0.394 | 0.537 | 0.594 | 0.334 | 0.766 | 0.832 |
0.068 | 0.073 | 0.189 | 0.327 | 0.394 | 0.537 | 0.334 | 0.594 | 0.766 | 0.832 |
0.068 | 0.073 | 0.189 | 0.327 | 0.394 | 0.334 | 0.537 | 0.594 | 0.766 | 0.832 |
0.068 | 0.073 | 0.189 | 0.327 | 0.334 | 0.394 | 0.537 | 0.594 | 0.766 | 0.832 |
If you do the extra credit, please report timing for three sets of experiments: mergesort, the original shellsort, and this modified shellsort.