/*这种题目一看就知道可以用partition算法做。。。 和上面一题几乎一样的的再敲一遍代码把 这种方法的弊端是 要改变原来的数组 还有一种O(nlogk) 的算法就是维护一个最大堆 这牙膏不改变原来数组但是堆。现在让我写 我已经写不出来了 就用有限队列就可以还可以用红黑数RBtree stl的set map 都是用红黑树的rbtree就是通过把节点分为红色和黑色两种颜色 然后一定的规则。。保证一定程度的树平衡可以用set multiset*/#include<iostream>#include<cstdio>#include<queue>#include<cstdlib>using namespace std;int RandInRange(int a,int b){ return rand()%(b-a)+a;}void Swap(int & a,int &b){ int tmp=a; a=b; b=tmp;}int Partition(int * arr,int len,int start,int end){ int index=RandInRange(start,end); int small=start-1; swap(arr[index],arr[end]); for(index=start;index<end;++index) { if(arr[index]<arr[end]) { small++; if(small!=index) { swap(arr[small],arr[index]); } } } ++small; swap(arr[small],arr[index]); return small;}/*O(n)的算法 但是要改变原来的数组*/void FindKMinNum(int * arr,int len,int k){ int start=0; int end=len-1; int index=Partition(arr,len,start,end); while(index!=k) { if(index>k) { end=index-1; index=Partition(arr,len,start,end); } else { start=index+1; index=Partition(arr,len,start,end); } } for(int i=0;i<k;++i) { printf("%d ",arr[i]); } printf("\n");}/*priority_queue就是最大堆。*/void FindKMinNum_2(int * arr,int len,int k){ priority_queue<int> pq; if(k>len) k=len; for(int i=0;i<k;++i) pq.push(arr[i]); for(int i=k;i<len;++i) { if(arr[i]<pq.top()) { pq.pop(); pq.push(arr[i]); } } while(!pq.empty()) { printf("%d ",pq.top()); pq.pop(); } printf("\n");}int main(){ int arr[]={4,5,1,6,2,7,3,8}; int len=sizeof arr/sizeof *arr; int k=4; FindKMinNum(arr,len,k); FindKMinNum_2(arr,len,k); return 0;}