home *** CD-ROM | disk | FTP | other *** search
-
- /* Shellsort is a variation on Insertion Sort that is virtually unbeatable
- * on small data sets. Insertion Sort is slow because it only exchanges
- * adjacent elements. Shellsort circumvents this by allowing the exchange
- * of elements that are farther apart. It works by first performing Insertion
- * Sort on subsets of the data. For example, Shellsort might first sort
- * the set of elements 1, 6, 11, 16... relative to each other--the effect
- * is that the elements in that subset are moved much closer to their final
- * positions. At first the sets are wide-spread, perhaps every fortieth
- * element. Then it repeats using a tighter set, perhaps every fourteenth
- * element, then every fourth element. Each of these passes is much cheaper
- * than a traditional Insertion Sort pass. The effect of the passes is that
- * the data set is mutated to be in "almost sorted" order. The final insertion
- * sort pass can then go very quickly because insertion sort does very well on
- * almost sorted data. In other words, at first the elements take large leaps
- * to the general location they belong and successively smaller steps move the
- * element to its precise place. I call this algorithm "inscrutable sort"
- * because even after having coded the algorithm, I still have trouble
- * following the animation. No one has been able to analyze this algorithm
- * rigorously; the functional form of the running time is conjectured to be
- * O(N^1.25). Shellsort may be a bit mysterious, but it is an good general
- * purpose sort since it has excellent performance and the code you must write
- * is only slightly more complex than Insertion Sort.
- *
- * Author: Julie Zelenski, NeXT Developer Support
- * You may freely copy, distribute and reuse the code in this example.
- * NeXT disclaims any warranty of any kind, expressed or implied, as to
- * its fitness for any particular use.
- */
-
-
- #import "ShellSort.h"
-
-
- @implementation ShellSort:GenericSort
-
-
- - init;
- {
- [super init];
- sortName = "Shellsort";
- sortNum = SHELL_SORT;
- return self;
- }
-
- - sort;
- /* Because Shellsort is a variation on Insertion Sort, it has the same
- * inconsistency that I noted in the InsertionSort class. Notice where I
- * subtract a move to compensate for calling a swap for visual purposes.
- */
- {
- #define STRIDE_FACTOR 3 // good value for stride factor is not well-understood
- // 3 is a fairly good choice (Sedgewick)
- int c,d, stride;
- BOOL found;
-
- [super sort];
- fcalls++;
- stride = 1;
- while (stride <= numElements)
- stride = stride*STRIDE_FACTOR +1;
-
- while (stride>(STRIDE_FACTOR-1)) { // loop to sort for each value of stride
- stride = stride / STRIDE_FACTOR;
- for (c = stride; c < numElements; c++){
- found = NO;
- d = c-stride;
- while ((d >= 0) && !found) { // move to left until correct place
- if ([self lessThan:d+stride :d]) {
- [self swap:d+stride with:d];//swap each time(visual effect)
- moves--; // subtract move to make fair
- d -= stride; // jump by stride factor
- } else
- found = YES;
- }
- }
- }
- [self sortDone];
- return self;
- }
-
- @end