Quick sort the simplest interval segmentation form has been introduced in the previous blog post, is one-way processing, the following describes the quick sort of other forms, are two-way processing, that is, the processing mode is smaller than pivot to the left, more than pivot to move to the right, when the two directions intersect, Move pivot to a position in the back of the intersection, and finally form three segments, respectively, greater than pivot, equal to pivot, greater than pivot. The advantage of bidirectional processing over one-way processing is that elements larger than pivot are moved once to the right and do not need to be moved again, while in one-way processing, elements larger than pivot continue to move to the right.
The first: directly take the rightmost element as pivot, and this type of segmentation code is as follows:
1 intPartition1 (int* PARR,intLintr) {2 //This split directly takes the rightmost element as pivot, so in the J loop it is necessary to determine whether it is out of bounds, because there may not be a smaller element than pivot on the far left, and I do not need it because the rightmost is pivot3 //find an element that is smaller and larger than pivot, and then swap the position if pivot is the largest, then no element will be exchanged (the last one, and itself)4 inti = L-1;5 intj = R-1;6 intPivot =Parr[r];7 while(true) {8 while(Parr[++i] <pivot) {}9 while(Parr[j] >pivot) {Ten--J; One if(J <l) A Break; - } - the if(I >=j)//can be taken =, which means pointing to the same position, without exchanging values - Break; -Swap (PArr + i, PARR +j); - } +Swap (PARR + j +1, PARR +R); - returnJ +1; +}
The second type: randomly split element pivot
The problem with the first approach is that if the array is sorted in descending order, then the rightmost element is the worst choice, because the smallest element is taken, and the algorithm turns to the left and the other elements are not moved. Randomly select pivot, you can get a better average expected performance, where the code is not affixed, as in front of the same, just pivot is randomly taken, and then the random number to the right. The premise is that the probability that all elements in the array appear is random.
The Third kind: The fast sort of three-sample segmentation
It means to take L, (L+r)/2,r of the three index position elements, and then put the smallest element on the left, the middle of the large elements as pivot on the far right, and then split the array, the reason is to use the middle large element, because this can achieve the average expected performance. In addition, you can do this in the first form, randomly three elements, then sort them again, then slice them.
The advantage of three sampling is that, in addition to avoiding the worst elements to be used for slicing, the second is to remove the cross-check of the while loop in the 12th case. The code is as follows:
1 void_SORT3 (int* PARR,intLintr) {2 if(R-l >=2) {3 intm =_partition3 (PARR, L, R);4_sort3 (PARR, L, M-1);5 _sort3 (PARR, M, R);6 }7 Else {8 if(Parr[l] >Parr[r])9Swap (PARR + L, PARR +R);Ten } One } A - intPartition3 (int* PARR,intLintr) { - //this splits the left and right three elements, then takes the middle large element as pivot, so in the J loop, there is no need to judge J >= 0, because there must be a smaller element than pivot to the left . the //if it is already ordered, then no elements will be exchanged, only the last one, and itself - intM = (R + L)/2; - if(Parr[l] >Parr[r]) -Swap (PARR + L, PARR +R); + if(Parr[r] >Parr[m]) -Swap (PARR + R, PArr +m); + if(Parr[l] >Parr[r]) ASwap (PARR + L, PARR +R); at - inti =l; - intj =R; - intPivot =Parr[r]; - - while(true) { in //When I reaches the right R, Parr[i]==pivot, while interrupts, does not cross - while(Parr[++i] <pivot) {} to + //when J reaches the leftmost L, Parr[l]<pivot, while interrupts, does not cross - while(Parr[--j] >pivot) {} the * if(I >=j) $ Break;Panax Notoginseng -Swap (PArr + i, PARR +j); the } +Swap (PARR + (++j), PARR +R); A returnJ; the}
Fourth: three-orientation segmentation, fast sequencing for a large number of repeating elements
take the rightmost element directly to pivot, if you can take the most of the same elements as pivot that is best, can minimize the data movement, The code is as follows:
1 voidQuickSort (int* PARR,intLintr) {2 if(R >l) {3 inti =l;4 intPivot =Parr[r];5 intLow =l;6 intHigh =R;7 while(I <=High ) {8 if(Parr[i] <pivot) {9 //this step, unless the following two else has been executed to, otherwise all is with itself in exchange valueTenSwap (PARR + (low++), PARR + i++); One //The elements smaller than pivot are shifted to the left, and low only increases at this time . A } - Else if(Parr[i] >pivot) { -Swap (PARR + (high--), PARR +i); the //the elements that are larger than pivot are shifted to the right, and high only decreases at this time . - } - Else { -++i; + } - } +QuickSort (PARR, L, Low-1); AQuickSort (PARR, High +1, R); at } -}
Several variations of the quick sort