*************************************** Reprint Please specify the Source: Http://blog.csdn.net/lttree ********************************************
Chapter One: Division and recursion
Linear time Selection
Algorithm Description:
Given the n elements in a linear sequence set and an integer k,1≤k≤n, it is required to find out the element K small in these n elements. That is, if the n elements are arranged in their linear order, the element in the K position is the element to be found. When K=1, is to find the smallest element, k=n, is to find the largest element, when k= (n+1)/2, is to find the median.
Algorithm Analysis:
In some special cases, it is easy to design a linear time algorithm for solution selection problem. For example, finding the smallest and largest elements of n elements can obviously be done in an O (n) time. If K≤n/log (n), the heap sorting algorithm can be used to find the K small element in O (N+klog (n)) = O (n) time, as well as when K≥n-n/log (n).
The general choice problem, especially the choice of median, seems to be harder than finding the smallest element. But in fact, in the sense of progressive order, they are the same. General selection issues can also be resolved within O (n) time.
This discussion of general selection problem of a divide-and-conquer algorithm randomizedselect. This algorithm is designed to mimic the fast sorting algorithm. The basic idea is to recursively divide the input array.
☆ NOTE: This algorithm differs from the fast sorting algorithm: This algorithm only recursively handles one of the sub-arrays that are partitioned. ☆
Algorithm program:
<span style= "Font-family:comic Sans MS;" > #include <iostream> #include <ctime> #include <cstdlib>using namespace Std;template <class Type>void Swap (type& x,type& y) {Type temp = x; x = y; y = temp;} int Random (int l, int r) {srand (unsigned) time (NULL)); int rd = rand ()% (r-l+1) +l; return Rd;} Partition function Template <class type>int Partition (Type a[],int l,int r) {int i = L,j = R + 1; Type temp = a[l]; while (true) {while (A[++i] < temp && I < R); while (A[--j] > Temp); if (i >= j) break; Swap (A[i],a[j]); } A[l] = A[j]; A[J] = temp; return J;} Template<class type>int randomizedpartition (Type a[],int l,int r) {int tem = RANDOM (L,R); Swap (A[tem],a[l]); Return Partition (A,L,R);} Template <class type>type randomizedselect (Type a[],int l,int r,int k) {if (L = = r) return a[l]; int tem,j; TEM = randomizedpartition (A,L,R); j = tem-L + 1; if (k <= j) return Randomizedselect (A,L,TEM,K); else return Randomizedselect (A,TEM+1,R,K-J);} </span>
Here's the function:
--swap exchanging values for two elements
--random Take two random numbers in the interval
--partition is also seen in the fast line, that is, the first number is the standard, less than it is on its left, greater than it on its right
--randomizedpartition added a random number of partition, this time it is not necessarily the first number as the standard, in the range of a random number as the standard
--randomizedselect L to R, K small element
Algorithm Explanation:
In the above algorithm program, after executing the function randomizedpartition, the array a[l:r] will be divided into two parts: A[l:tem] and a[tem+1:r], but the left part of each element is not much more than the right part of any one element.
Then the number of elements in the left part of J, if K≤j, the A array of k small element is located in the sub-array A[l:tem]. The opposite is located in the A[tem+1:r]. So only one sub-array needs to be extended.
In the worst case, the algorithm randomizedselect requires the calculation time of Ω (n^2). In spite of this, the average performance of the algorithm is good, because the random number of randomizedpartition uses random numbers generator, in this condition can prove that the algorithm randomizedselect can be in O (n) Find the nth element in the average time in the N INPUT element.
Algorithm optimization:
Next we discuss an algorithm select that can complete the selection task in the worst case with O (n) time.
If a dividing datum can be found in linear time, so that the length of the two sub-arrays that are divided by this datum is at least m times the length of the tuple (0 < M < 1), then the selection task can be done in the worst case with an O (n) time.
For example, M=9/10, the resulting subarray length of the algorithm recursive call is reduced by at least 1/10. So, in the worst case, the time required for the algorithm is T (n) to satisfy the recursive T (n) ≤t (9N/10) +o (n). Thus, t (n) =o (n) can be used.
The algorithm steps are as follows:
<1> will all the number of N to each 5 divided into a group of common groups, will be less than 5 of the group ignored, and then use any sort of algorithm, because only 5 numbers are sorted, so any one sort method can be. The elements in each group are sorted and then the median of each group is taken, and The median number is obtained .
<2> Take the median of this median, and if it is an even number, look for the larger of its 2 median as the dividing datum.
<3> divides all the numbers into two parts, less than the base on the left, and the right side of the base greater than equals. In this case, the baseline X is found to be at least larger than an element. Because there are 2 elements in each group that are less than the median of this group, there is a less than baseline, the median is in, that is, the median number is less than the reference x. So at least one element is less than the base x. The benchmark X is also at least smaller than an element. When N≥75 is ≥N/4, the length of the 2 sub-arrays that are divided by this datum is reduced by at least 1/4.
Program:
<span style= "Font-family:comic Sans MS;" >template <class type>void Swap (type& x,type& y) {Type temp = x; x = y; y = temp;} int Random (int l, int r) {//Srand ((unsigned) time (NULL)); int rd = rand ()% (r-l+1) +l; return Rd;} Template <class type>int Partition (Type a[],int l,int r,type x) {int i = L-1,j = R + 1; while (true) {while (a[++i]<x && i<r); while (A[--J]>X); if (i>=j) break; Swap (A[i],a[j]); } return J;} Template <class type>void bubblesort (Type a[],int L, int r) {for (int j = l; j < R-1; ++j) for (int i = l; i < r-1-j; ++i) if (A[i] > A[i+1]) Swap (a[i],a[i+1]);} Template <class type>type Select (Type a[],int l, int r,int k) {if ((R-l) < 75) {//element less than 75, directly with a Sort the rows on the line (bubbling here) bubblesort (A,L,R); return a[l+k-1]; } for (int i = 0; I <= (r-l-4)/5; ++i) {//element is divided into a group of 5, sorted separately, and place the median of the group in the a[l+i] swap position//so that all the median is arranged at the leftmost side of the array to further find the median median bubblesort (a,l+5*i,l+5*i+4); Swap (A[l+5*i+2],a[l+i]); }//Find the median middle digit Type x = Select (a,l,l+ (r-l-4)/5, (r-l-4)/10); int i = Partition (a,l,r,x); int j = i-l+1; if (k<=j) return Select (A,L,I,K); else return Select (A,I+1,R,K-J);} </span>
*************************************** Reprint Please specify the Source: Http://blog.csdn.net/lttree ********************************************
The path of re-picking algorithm--linear time selection