Chapter 7 Sorting
See also here
Preliminaries
void X_sort (ElementType A[], int N) ;
Insertion Sort
void InsertionSort (ElementType A[], int N) { int j, p; ElementType tmp; for (p = 1 ; p < N; ++p){ tmp = A[p]; for (j = p; j > 0 && A[j - 1 ] > tmp; --j){ A[j] = A[j - 1 ]; } A[j] = tmp; } }
T ( N ) = O ( N ) ∼ O ( N 2 ) T(N)=O(N)\sim O(N^2) T ( N ) = O ( N ) ∼ O ( N 2 )
Lower Bound for Simple Sorting Algorithm
Inversion : ordered pair (i, j) that i < j and A[i] > A[j]
For simple sorting algorithm, one swap operation removes one inversion, so that T ( N , I ) = O ( I + N ) T(N,I)=O(I + N) T ( N , I ) = O ( I + N )
Theorem
Average inversions in an random array: I = N ( N − 1 ) / 4 I=N(N-1)/4 I = N ( N − 1 ) /4
T ( N ) = Ω ( N 2 ) T(N)=\Omega(N^2) T ( N ) = Ω ( N 2 )
Swap elements that are far apart could remove some inversions at once
Shellsort
多次间隔的插入排序
Define an increment sequence h 1 = 1 < h 2 < … < h t h_1=1<h_2<…<h_t h 1 = 1 < h 2 < … < h t
Define an h k h_k h k -sort at each phase for k = t , t − 1 , … , 1 k=t,t-1,…,1 k = t , t − 1 , … , 1
h k − 1 h_{k-1} h k − 1 -sort remains h k h_k h k -sort
Shellsort is an in-place but not stability sorting algorithm
Insertion sort is in-place and stability sorting algorithm
Shell’s Increment Sequence
h t = f l o o r ( N / 2 ) , h k = f l o o r ( h k + 1 / 2 ) : 1 , 2 , 4 , 8 , … h_t=floor(N/2),h_k=floor(h_{k+1}/2):1,2,4,8,…
h t = f l oor ( N /2 ) , h k = f l oor ( h k + 1 /2 ) : 1 , 2 , 4 , 8 , …
T w s t ( N ) = O ( N 2 ) T_{wst}(N)=O(N^2) T w s t ( N ) = O ( N 2 )
Pairs of increments are necessarily relatively prime
Hibbard’s Increment Sequence
h k = 2 k − 1 : 1 , 3 , 7 , 15 , … h_k=2^k-1:1,3,7,15,…
h k = 2 k − 1 : 1 , 3 , 7 , 15 , …
T w s t ( N ) = O ( N 3 / 2 ) > O ( N log N ) T_{wst}(N)=O(N^{3/2})>O(N\log N) T w s t ( N ) = O ( N 3/2 ) > O ( N log N )
T a v g = O ( N 5 / 4 ) T_{avg}=O(N^{5/4}) T a vg = O ( N 5/4 )
Sedgewick’s Increment Sequence
h k = 9 × 4 i − 9 × 2 i + 1 o r 4 i − 3 × 2 i + 1 h_k=9\times4^i-9\times2^i+1\ \mathrm{or}\ 4^i-3\times2^i+1
h k = 9 × 4 i − 9 × 2 i + 1 or 4 i − 3 × 2 i + 1
T w s t ( N ) = O ( N 4 / 3 ) T_{wst}(N)=O(N^{4/3}) T w s t ( N ) = O ( N 4/3 )
T a v g ( N ) = O ( N 7 / 6 ) T_{avg}(N)=O(N^{7/6}) T a vg ( N ) = O ( N 7/6 )
Heapsort
in-place but not stable
Implement 1
{ BuildHeap(H); for (i = 0 ; i < N; ++i) TmpH[i] = DeleteMin(H); for (i = 0 ; i < N; ++i) H[i] = TmpH[i]; }
T ( N ) = N log N T(N)=N\log N T ( N ) = N log N
S ( N ) = 2 N S(N)=2N S ( N ) = 2 N
Implement 2
See also
void percolateDown (ElemType* base, size_t begin, size_t end,int (*ptrCompFunc)(const ElemType* x, const ElemType* y)) { size_t parent, lChild, rChild; parent = begin, lChild = 2 * parent + 1 , rChild = lChild + 1 ; while (parent < end){ size_t max = parent; if (lChild < end && !(*ptrCompFunc)(base + lChild, base + max)) max = lChild; if (rChild < end && !(*ptrCompFunc)(base + rChild, base + max)) max = rChild; if (parent == max) break ; swap(base + parent, base + max); parent = max, lChild = 2 * parent + 1 , rChild = lChild + 1 ; } } void heapSort (ElemType* base, size_t n, int (*ptrCompFunc)(const ElemType* x, const ElemType* y)) { for (size_t i = n / 2 - 1 ; ; --i){ percolateDown(base, i, n, ptrCompFunc); if (i == 0 ) break ; } for (size_t i = n - 1 ; ; --i){ swap(base, base + i); percolateDown(base, 0 , i, ptrCompFunc); if (i == 0 ) break ; } }
T a v g ( N ) = 2 N log N − O ( N log log N ) T_{avg}(N)=2N\log N-O(N\log\log N) T a vg ( N ) = 2 N log N − O ( N log log N )
Mergesort
See Also
Quicksort
the fastest (not) sorting algorithm
See also
Implementation
T b s t ( N ) = O ( N log N ) T_{bst}(N)=O(N\log N) T b s t ( N ) = O ( N log N )
T w s t ( N ) = O ( N 2 ) T_{wst}(N)=O(N^2) T w s t ( N ) = O ( N 2 )
Picking the Pivot
wrong way
Pivot = A[0]
safe maneuver
Pivot = random select from A[]
random number generation is expensive
median-of-three partitioning
Pivot = median(left, center, right)