A, segmentation (partition) algorithm Introduction
The so-called segmentation algorithm, first selects a pivot element, and then divides the elements in the array into two parts: the part that is smaller than the pivot element is located to the left of the pivot element, and the part larger than the pivot element is located to the right of the pivot element
At this point, the position of the pivot element in the array is "permanently determined"---the entire array is sorted, and the position of the pivot element does not change.
In addition, the selection of pivot elements is important for the segmentation algorithm. In general, the ultimate pursuit is: divide the array equally. Therefore, as much as possible, the selection of the pivot element is randomized and close to the median.
The pivot element is selected using the "three-digit-in" method.
For a quick sort sorting algorithm, refer to: http://www.cnblogs.com/hapjin/p/5518922.html
Two, the realization of the segmentation algorithm
1 //splits an array into two parts. Part is larger than pivot (pivot element) and the other part is smaller than pivot2 Private Static intParition (int[] arr,intLeftintRight ) {3 4 intPivot =Media3 (arr, left, right);5 inti =Left ;6 intj = right-1;//Note that in Media3 () arr[right-1] is pivot7 8 for(;;)9 {Ten while(Arr[++i] <pivot) {} One while(Arr[--j] >pivot) {} A if(I <j) - swap (arr, I, j); - Else the Break; - } - -Swap (arr, I, right-1);//Restore pivot, place the pivot element in the appropriate location: ARR is smaller than pivot and the right side is larger than pivot + returnI//returns the index of pivot -}
① the 4th line, the pivot element is selected by the "three-digit-in" method. In "three-count", some optimizations were made: Place the pivot element at the second-to-last position at the end of the array. Specific reference media3 ()
Note that: When the input array length is 1 or 2 o'clock, partition will appear to cross the line (but for the fast row, when the number of team leader is very small, in fact, can not partition, but directly with the insertion sort). Therefore, you can add the following modifications.
1 //splits an array into two parts. Part is larger than pivot (pivot element) and the other part is smaller than pivot2 Private Static intParition (int[] arr,intLeftintRight ) {3 4 intPivot =Media3 (arr, left, right);5 inti =Left ;6 intj = right-1;//Note that in Media3 () arr[right-1] is pivot7 8 //Arrays in special cases, such as arrays with lengths of less than 39 if(I >=j)Ten returni; One A for(;;) - { - while(Arr[++i] <pivot) {} the while(Arr[--j] >pivot) {} - if(I <j) - swap (arr, I, j); - Else + Break; - } + ASwap (arr, I, right-1);//Restore pivot places the pivot element in the appropriate location: The left element of arr is smaller than pivot and the right side is larger than pivot at returnI//returns the index of pivot -}
Take a look at the three-digit algorithm, where there is a special case: when the number of elements in the array is not 3 .... What to do?
1 //three count, when selecting a pivot element randomly in a fast row2 Private Static intMEDIA3 (int[] arr,intLeftintRight ) {3 if(Arr.length = = 1)4 returnArr[0];5 6 intCenter = (left + right)/2;7 8 //find the minimum value in three numbers and put it to Arr[left]9 if(Arr[center] <Arr[left])Ten swap (arr, left, center); One if(Arr[right] <Arr[left]) A swap (arr, left, right); - - //put the middle number in the Arr[media] the if(Arr[center] >Arr[right]) - Swap (arr, center, right); - -Swap (arr, center, right-1);//try to put the big elements on the right side--put the privot on the right side, simplifying the split operation (partition). + returnARR[RIGHT-1];//returns the number of the middle size -}
When there is only one element in the array, the 18th row crosses the line. To prevent this, the 3–4 line is judged by the length of the array. When there are only two elements in the array, it is actually equivalent to Center=left, so the program is no problem.
Three, the application of the segmentation algorithm
Given an array, an element in the array appears more than half the size of the array to find this element.
For example, input: [2,5,4,4,5,5,5,6,5], Output 5
This problem can actually be translated into solving the median problem. Because, when the array is ordered, the element with more than half occurrences must be in the middle of the array.
The so-called median is the assumption that the array is ordered in the case of the middle element. IE ARR[ARR.LENGTH/2]
To solve the median, of course, you can sort the array first, but the ordering time complexity is O (NLOGN), that there is no faster algorithm?
Of course there is. is the use of partition segmentation algorithm to achieve.
1 //find out which element of N/2 is the largest in Arr2 Public Static intMedia_number (int[] arr) {3 intleft = 0;4 intright = Arr.length-1;5 intCenter = (left + right)/2;6 7 intPivot_index =parition (arr, left, right);//index of PIVOT element8 9 while(Pivot_index! =Center)Ten { One if(Pivot_index >Center) { Aright = Pivot_index-1; -Pivot_index =parition (arr, left, right); - } the Else{ -left = Pivot_index + 1; -Pivot_index =parition (arr, left, right); - } + } - returnArr[center]; +}
Here the recursive expression T (n) =t (N/2) +o (n), O (n) represents the cost of dividing the array into two parts.
So time complexity is O (N)
Four, references
A quick sort of sorting algorithm summary
Entire complete code
Public classMiddle_large {//find out which element of N/2 is the largest in Arr Public Static intMedia_number (int[] arr) { intleft = 0; intright = Arr.length-1; intCenter = (left + right)/2; intPivot_index =parition (arr, left, right); while(Pivot_index! =Center) { if(Pivot_index >Center) { Right= Pivot_index-1; Pivot_index=parition (arr, left, right); } Else{ Left= Pivot_index + 1; Pivot_index=parition (arr, left, right); } } returnArr[center]; } //splits an array into two parts. Part is larger than pivot (pivot element) and the other part is smaller than pivot Private Static intParition (int[] arr,intLeftintRight ) { intPivot =Media3 (arr, left, right); inti =Left ; intj = right-1;//Note that in Media3 () arr[right-1] is pivot//Arrays in special cases, such as arrays with lengths of less than 3 if(I >=j)returni; for(;;) { while(Arr[++i] <pivot) {} while(Arr[--j] >pivot) {} if(I <j) Swap (arr, I, j); Else Break; } swap (arr, I, right-1);//Restore pivot places the pivot element in the appropriate location: The left element of arr is smaller than pivot and the right side is larger than pivot returnI//returns the index of pivot } //three count, when selecting a pivot element randomly in a fast row Private Static intMEDIA3 (int[] arr,intLeftintRight ) { if(Arr.length = = 1) returnArr[0]; intCenter = (left + right)/2; //find the minimum value in three numbers and put it to Arr[left] if(Arr[center] <Arr[left]) swap (arr, left, center); if(Arr[right] <Arr[left]) swap (arr, left, right); //put the middle number in the Arr[media] if(Arr[center] >Arr[right]) swap (arr, center, right); Swap (arr, center, right-1);//try to put the big elements on the right side--put the privot on the right side, simplifying the split operation (partition). returnARR[RIGHT-1];//returns the number of the middle size } Private Static voidSwapint[] arr,intLeftintRight ) { intTMP =Arr[left]; Arr[left]=Arr[right]; Arr[right]=tmp; } Public Static voidMain (string[] args) {int[] arr = {5,6,8,4,1,5,5,5,5}; intresult =Media_number (arr); SYSTEM.OUT.PRINTLN (result); }}
Analysis and application of fast segmentation algorithm