|
|
1.1 ! root 1: ! 2: /* True to its name, this sort is fast, but it is not without its faults. ! 3: * It works by partitioning a data set into two parts and then recursively ! 4: * sorting the parts. It divides the data by choosing a pivot value and ! 5: * moving all elements less than the pivot into one partition, all elements ! 6: * greater than the pivot go to the other. Each of the partitions are split ! 7: * again with a new pivot, and following the magic trail of recursion it ! 8: * arrives at a sorted data set. It is fast, even with the overhead of ! 9: * recursion. However, with a poor pivot choice, it can slow down enormously. ! 10: * A poor pivot choice is one that divides the data lopsidedly instead of ! 11: * creating two fairly equal partitions. For this reason, Quicksort works ! 12: * particularly poorly on data that is already sorted. Already sorted data ! 13: * is, in fact, its worst case at O(n^2) whereas its average case is O(nlogn). ! 14: * ! 15: * Author: Julie Zelenski, NeXT Developer Support ! 16: * You may freely copy, distribute and reuse the code in this example. ! 17: * NeXT disclaims any warranty of any kind, expressed or implied, as to ! 18: * its fitness for any particular use. ! 19: */ ! 20: ! 21: ! 22: #import "QuickSort.h" ! 23: ! 24: ! 25: @implementation QuickSort:GenericSort ! 26: ! 27: - init; ! 28: { ! 29: [super init]; ! 30: sortName = "Quicksort"; ! 31: sortNum = QUICK_SORT; ! 32: return self; ! 33: } ! 34: ! 35: - (int)partition:(int)begin to:(int)end ! 36: { ! 37: int left, pivot, right; ! 38: ! 39: fcalls++; ! 40: left = begin; ! 41: right = end; ! 42: while (left < right) { ! 43: while ([self lessThan:begin :right]) ! 44: right--; // move to find one that doesn't belong on right side ! 45: while ((left < right) && (![self lessThan:begin :left])) ! 46: left++; // move to find one that doesn't belong on left side ! 47: if (left < right) ! 48: [self swap:right with:left]; // swap the two elements ! 49: } ! 50: pivot = right; ! 51: [self swap:pivot with:begin]; // move the pivot to the middle ! 52: return pivot; ! 53: } ! 54: ! 55: - quicksort:(int)begin to:(int)end ! 56: { ! 57: int pivot; ! 58: ! 59: fcalls++; ! 60: if (begin < end) { ! 61: pivot = [self partition:begin to:end]; // divide into two partitions ! 62: [self quicksort:begin to:(pivot-1)]; // sort first partition ! 63: [self quicksort:(pivot+1) to:end]; // sort second partition ! 64: } ! 65: return self; ! 66: } ! 67: ! 68: ! 69: - sort ! 70: { ! 71: [super sort]; ! 72: [self quicksort:0 to:(numElements -1)]; ! 73: [self sortDone]; ! 74: return self; ! 75: } ! 76: ! 77: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.