100万个数中找出最大的前K个数
拿到这个题目我想到了很多方法,但是在我想到的方法中,要把在100万个数中找到前k个数,都不适用。最后通过我的不断研究,我想到了我认为最简单的方法,就是利用堆来做这道题目。
下面我分析一下我用堆排序的思路:
1.我先建一个大小为k的堆。
2.把100万中前k个数放到这个堆中。
3.把这个堆调成小堆。
4.把100万个从k到100万之间的数字拿出来和堆的根结点作比较。
5.如果根结点小于这之间的某一个数,就把这个数拿给根结点,然后继续调成小堆。否则继续找
6.直到找完这100万个数,堆中放的就是最大的前k个数。
代码如下:
//下调void_AdjustDown(int*arr,intparent,intsize){intchild=2*parent+1;while(child<size){//child+1<size保证是最后一个节点if(child+1<size&&arr[child]>arr[child+1]){child++;//保证是孩子结点最大的一个节点}//交换if(arr[child]<arr[parent]){swap(arr[child],arr[parent]);parent=child;child=2*parent+1;}else{break;}}}int*Find(int*arr,intk,intN){assert(arr);assert(k>0);int*str=newint[k];//把前k个元素放在堆中for(inti=0;i<k;i++){str[i]=arr[i];}//调成最小堆for(intj=(k-2)/2;j>=0;j--){_AdjustDown(str,j,k);}//然后k到N的所有数与堆中的根结点相比较for(intn=k;n<N;n++){if(str[0]<arr[n])//如果根结点小于堆中k到N中的某一元素{str[0]=arr[n];//把这个元素赋值给根结点_AdjustDown(str,0,k);//再一次调成最小堆}}returnstr;delete[]str;}
希望这个对你们有帮助。期待你们的回复,有什么不对的地方可以指出来啊。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。