Original: http://blog.csdn.net/left_la/article/details/8206405
Three steps for a quick sort:
1, decomposition: the array a[l ... R] divided into two (possibly empty) sub-arrays of a[l ... P-1] and A[P+1...R], making a[l ... Each element in P-1] is less than or equal to A (p), and is less than or equal to the element in A[P+1...R]. Subscript P is also calculated during this partitioning process.
2. Solve: Fast sorting by recursive call, array a[l ... P-1] and A[P+1...R] sort.
3. Merging: Because two sub-arrays are sorted in place, merging them does not require manipulation of the entire array a[l. R] already sorted.
1. The basic implementation of fast sequencing:
QUICKSORT (A, L, R) if l < r = partion (A, L, R) QUICKSORT (A, L, p-1) QUICKSORT (A, P+1
The main idea of two-way partion algorithm:
Move from left to find a element that's not
Move from right to find a element that's not greater
Stop if pointers has crossed
Exchange
Implementation code:
intPartitionDoubleAintLeftintRight ) { Doublex =A[right]; inti = left-1, j =Right ; for (;;) { while(A[++i] <x) {} while(A[--j] > x) {if(J==left) Break;} if(I <j) Swap (A[i], a[j]); Else Break; } swap (A[i],a[right]); returni; } voidQuickSort1 (DoubleAintLeftintRight ) { if(left<Right ) { intp =partition (A, left, right); QuickSort1 (A, left, p-1); QuickSort1 (A, p+1, right); } }
2. Non-recursive algorithm: In fact, is to manually use the stack to store each block of the starting point of the fast row, stack non-empty loop to get the middle of the stack.
Implementation code:
voidQuickSort2 (DoubleAintLeftintRight ) {Stack<int>T; if(left<Right ) { intp =partition (A, left, right); if(P-1>Left ) {T.push (left); T.push (P-1); } if(p+1<Right ) {T.push (P+1); T.push (right); } while(!T.empty ()) { intR =T.top (); T.pop (); intL =T.top (); T.pop (); P=partition (A, L, R); if(P-1>l) {T.push (L); T.push (P-1); } if(p+1<r) {T.push (P+1); T.push (R); } } } }
3. Three-way division fast sorting algorithm:
Implementation code:
voidQuicksort3way (DoubleA[],intLeftintRight ) { if(Left <Right ) { Doublex =A[right]; inti = left-1, j = right, p = left-1, q =Right ; for (;;) { while(A[++i] <x) {} while(A[--j] > x) {if(J==left) Break;} if(I <j) {Swap (A[i], a[j]); if(A[i] = = x) {p++; swap (a[p], a[i]);} if(A[j] = = x) {q--; swap (A[q], a[j]);} } Else Break; } swap (A[i], a[right]); J= I1; i=i+1; for(intK=left; k<=p; k++, j--) Swap (A[k], a[j]); for(intk=right-1; k>=q; K--, i++) Swap (A[i], a[k]); Quicksort3way (A, left, j); Quicksort3way (A, I, right); } }
4. Test the code:
#include <iostream>#include<stack>#include<ctime>using namespacestd;//generating num Random numbers in the range (A, b)Double* Createrand (DoubleADoubleBintnum) { Double*C; C=New Double[num]; Srand ((unsignedint) Time (NULL)); for(intI=0; i<num; i++) C[i]= (b-a) * (Double) rand ()/rand_max +A; returnC;}//Two-way division, get the middle axis, the number of axes left is less than the axis, the axis right number is greater than the axisDoublePartitionDoubleBintLeftintRight ) { ...}//1. Recursive fast sequencing, using two-way DivisionvoidQuickSort1 (DoubleAintLeftintRight ) { ...}//2. Non-recursive fast sequencing, manually use the stack to store the starting point of each block fast, stack non-empty time loop to get the middle axis into the stackvoidQuickSort2 (DoubleAintLeftintRight ) { ...}//3. Using three-way division to achieve recursive fast orderingvoidQuicksort3way (DoubleA[],intLeftintRight ) { ...}voidMain () {Double*a, *b, *C; intk=10000000; time_t start,end; A= Createrand (0,1, K); b= Createrand (0,1, K); C= Createrand (0,1, K); Start=clock (); QuickSort1 (A,0, K-1); End=clock (); cout<<"1.recursive"<<1.0* (End-start)/clocks_per_sec<<"seconds"<<Endl; Start=clock (); QuickSort2 (b,0. Ko1); End=clock (); cout<<"2.non-recursive"<<1.0* (End-start)/clocks_per_sec<<"seconds"<<Endl; Start=clock (); Quicksort3way (c,0, K-1); End=clock (); cout<<"3.3"<<1.0* (End-start)/clocks_per_sec<<"seconds"<<Endl; cout<<Endl; System ("Pause");}
Result
1.recursive 1.951 seconds
2.non-recursive 2.224 seconds
3.3 1.677 seconds
The results show that the non-recursive algorithm is less efficient than the recursive algorithm because of the need to save the variables in the process of manual algorithm, and the 3-way partition algorithm reduces the complexity of the fast-line by using a small amount of redundant switching, and the execution efficiency is higher than the traditional 2-way fast algorithm.
"Turn" implementation of three kinds of fast sorting algorithms (recursive algorithm, non-recursive algorithm, three-way division fast sorting)