For once, suppose I asked for a small element of K. Or to ask for the first k elements, I might sort the elements first, and then just find out, but now there's a better idea.
First, the linear time to find the small element k
This algorithm is an algorithm based on the thought of divide and conquer.
Its detailed idea of division is as follows:
1. Decomposition: A[p,r] is decomposed into a[p,q-1] and A[q+1,r] two parts. So that a[p,q-1] are less than a[q],a[q+1,r] are not less than a[q];
2. Solution: Suppose A[q] happens to be the K small element directly returned, assuming that the K element falls in the first half of the interval to a[p,q-1] recursive lookup. Otherwise, the lookup is recursive in a[q+1,r].
3. Merger: This issue does not need to be merged.
Its corresponding code such as the following:
intRandomziedselect (int*a,intPintRintK) {if(P==R)/// If the current interval is only one element, then this element must be what we ask for. returnA[P];intQ=randomparatition (A,P,R);/// random partitioning function intx=q-p+1;/// Find out the length between a[p,q] if(x==k)/// A[q] happens to be the K small element returnA[Q];if(x>k)/// x less than k description K small element between A[p,q-1] returnRandomziedselect (a,p,q-1, k);Else /// x greater than K description K small element in A[q+1,r], and is the k-x small element of this interval returnRandomziedselect (a,q+1, r,k-x);}
In fact, this process is very similar to the fast line, but why the time complexity of the NLGN is O (n), and the time complexity of the algorithm is only O (n.)? The basic reason is that the algorithm only has to deal with the half of the interval after decomposition, and not as fast as the two sides to deal with.
Of course this is just a simple analysis, and more detailed mathematical analysis is not to be said here. In fact, we can also use the nature of the heap to find out the K small element, we only need to establish a minimum heap and then adjust k-1 times, so the time complexity is O (n) +o ((k-1) LGN).
A complete code is given below:
#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include <ctime>#include <fstream>using namespace STD;intParatition (int*a,intPintR) {intKEY=A[R];inti=p-1; for(intj=p;j<r;j++)if(A[j]<key) {i++; Swap (a[i],a[j]); } Swap (a[i+1],a[r]);returni+1;}intRandomparatition (int*a,intPintR) {intX=rand ()% (r-p+1) +p;/// generate a random number between [P,r]Swap (a[x],a[r]);///Exchange A[x] and a[r], in fact, A[x] as the key value of the Division returnParatition (a,p,r);}intRandomziedselect (int*a,intPintRintK) {if(P==R)/// If the current interval is only one element, then this element must be what we ask for. returnA[P];intQ=randomparatition (A,P,R);/// random partitioning function intx=q-p+1;/// Find out the length between a[p,q] if(x==k)///a[q] happens to be the K small element returnA[Q];if(x>k)///x less than k description K small element in A[p,q-1] returnRandomziedselect (a,p,q-1, k);Else ///x greater than k description K small element in A[q+1,r], and is the k-x small element of this interval returnRandomziedselect (a,q+1, r,k-x);}intMain () {intb[ -]; Ifstream Fin ("Lkl.txt");intN,k;//cout<< "Please enter n,k:";fin>>n>>k;//cout<< "Please enter" <<n<< "elements:" <<endl; for(intI=1; i<=n;i++) fin>>b[i];intAns=randomziedselect (b,1, n,k); Sort (b +1, b+n+1); for(intI=1; i<=n;i++)cout<<b[i]<<" ";cout<<endl;cout<<"section"<<k<<"The small element is:"<<ans<<endl;return 0;}
Two. Using the heap to find the top k elements
The idea of this algorithm is simpler: Suppose we ask for an element of the top k in n elements. We will first create a minimum heap of the first k elements in these n elements, and then from K+1.
。。
n is inferred in turn. Assuming that an element is larger than the smallest element in the heap, we replace it with the smallest element in the heap and adjust the heap.
After all the elements have been checked, the K elements in the heap are the top k elements of the n elements. Time complexity O (k) +o ((n-k) lgk).
Code such as the following
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <fstream>using namespace STD;#define MAXN/// Minimum heap adjustment functionvoidMinheadfly (int*a,intIintHeadsize) {intl=i*2, r=2*i+1;intlargest;if(a[i]>a[l]&&l<=headsize) largest=l;Elselargest=i;if(a[largest]>a[r]&&r<=headsize) Largest=r;if(largest!=i) {swap (a[i],a[largest]); Minheadfly (a,largest,headsize); }}/// Minimum heap build functionvoidMinheadbuild (int*a,intN) { for(inti=n/2; i>=1; i--) Minheadfly (a,i,n);}/// minimum heap sorting function, from large to small sortvoidMinheadsort (int*a,intHeadsize) {intK=headsize; for(inti=headsize;i>=2; i--) {Swap (a[i],a[1]); k--; Minheadfly (A,1, k); }}/// ask for the first k elements of array BvoidPreKint*a,int*b,intNintk) {minheadbuild (a,k); for(inti=k+1; i<=n;i++)if(b[i]>a[1]) {a[1]=b[i]; Minheadfly (A,1, k); } minheadsort (A,k);cout<<"Front"<<k<<"The big element is:"<<endl; for(intI=1; i<=k;i++)cout<<a[i]<<" ";cout<<endl;}intA[MAXN],B[MAXN];intMain () {Ifstream fin ("Lkl.txt");intN,k;//cout<< "Please enter n,k:";fin>>n>>k;//cout<< "Please enter" <<n<< "elements:" <<endl; for(intI=1; i<=n;i++) {fin>>b[i];if(i<=k) a[i]=b[i]; } prek (A,b,n,k);return 0;}
The linear time of the algorithm introduction learning K-K elements + heap thought