Annotation of Examples/AppKit/SortingInAction/ShellSort.m, revision 1.1.1.1

1.1       root        1: 
                      2: /* Shellsort is a variation on Insertion Sort that is virtually unbeatable 
                      3:  * on small data sets.  Insertion Sort is slow because it only exchanges 
                      4:  * adjacent elements.  Shellsort circumvents this by allowing the exchange 
                      5:  * of elements that are farther apart.  It works by first performing Insertion 
                      6:  * Sort on subsets of the data.  For example, Shellsort might first sort 
                      7:  * the set of elements 1, 6, 11, 16... relative to each other--the effect 
                      8:  * is that the elements in that subset are moved much closer to their final 
                      9:  * positions.  At first the sets are wide-spread, perhaps every fortieth 
                     10:  * element.  Then it repeats using a tighter set, perhaps every fourteenth 
                     11:  * element, then every fourth element.  Each of these passes is much cheaper 
                     12:  * than a traditional Insertion Sort pass.  The effect of the passes is that 
                     13:  * the data set is mutated to be in "almost sorted" order.  The final insertion 
                     14:  * sort pass can then go very quickly because insertion sort does very well on 
                     15:  * almost sorted data.  In other words, at first the elements take large leaps 
                     16:  * to the general location they belong and successively smaller steps move the 
                     17:  * element to its precise place. I call this algorithm "inscrutable sort" 
                     18:  * because even after having coded the algorithm, I still have trouble 
                     19:  * following the animation.  No one has been able to analyze this algorithm 
                     20:  * rigorously; the functional form of the running time is conjectured to be 
                     21:  * O(N^1.25).  Shellsort may be a bit mysterious, but it is an good general 
                     22:  * purpose sort since it has excellent performance and the code you must write 
                     23:  * is only slightly more complex than Insertion Sort.
                     24:  *
                     25:  * Author: Julie Zelenski, NeXT Developer Support
                     26:  * You may freely copy, distribute and reuse the code in this example.  
                     27:  * NeXT disclaims any warranty of any kind, expressed or implied, as to 
                     28:  * its fitness for any particular use.
                     29:  */
                     30:  
                     31:  
                     32: #import "ShellSort.h"
                     33: 
                     34: 
                     35: @implementation ShellSort:GenericSort
                     36: 
                     37: 
                     38: - init;
                     39: {
                     40:     [super init];
                     41:     sortName = "Shellsort";
                     42:     sortNum = SHELL_SORT;
                     43:     return self;
                     44: }
                     45: 
                     46: - sort;
                     47: /* Because Shellsort is a variation on Insertion Sort, it has the same 
                     48:  * inconsistency that I noted in the InsertionSort class.  Notice where I 
                     49:  * subtract a move to compensate for calling a swap for visual purposes.
                     50:  */
                     51: {
                     52: #define STRIDE_FACTOR 3        // good value for stride factor is not well-understood
                     53:                                // 3 is a fairly good choice (Sedgewick)
                     54:     int c,d, stride;
                     55:     BOOL found;
                     56: 
                     57:     [super sort];
                     58:     fcalls++; 
                     59:     stride = 1;
                     60:     while (stride <= numElements)
                     61:       stride = stride*STRIDE_FACTOR +1;
                     62:     
                     63:     while (stride>(STRIDE_FACTOR-1)) { // loop to sort for each value of stride
                     64:        stride = stride / STRIDE_FACTOR;
                     65:        for (c = stride; c < numElements; c++){
                     66:            found = NO;
                     67:            d = c-stride;
                     68:            while ((d >= 0) && !found) { // move to left until correct place
                     69:                if ([self lessThan:d+stride :d]) {
                     70:                    [self swap:d+stride with:d];//swap each time(visual effect)
                     71:                    moves--;                    // subtract move to make fair
                     72:                    d -= stride;                // jump by stride factor
                     73:                } else
                     74:                    found = YES;
                     75:            }
                     76:        }
                     77:     }
                     78:     [self sortDone];
                     79:     return self;
                     80: }
                     81:        
                     82: @end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.