,,拿到这个题目我想到了很多方法,但是在我想到的方法中,要把在100年万个数中找到前k个数,都不适用。最后通过我的不断研究,我想到了我认为最简单的方法,就是利用堆来做这道题目。
,,下面我分析一下我用堆排序的思路:
,,1。我先建一个大小为k的堆。
,,2。100把万中前k个数放到这个堆中。
,,3。把这个堆调成小堆。
,,4。100把万个从k到100万之间的数字拿出来和堆的根结点作比较。
,,5。如果根结点小于这之间的某一个数,就把这个数拿给根结点,然后继续调成小堆,否则继续找
,,6。直到找完这100多万个数,堆中放的就是最大的前k个数。
代码如下:
//下调 void _AdjustDown (int * arr, int 父母,,int 大小) { int child =, 2, *, parent +, 1; while (child<大小) {//child +, 1, & lt;大小,保证是最后一个节点 if (child +, 1, & lt;, size&, arr(孩子),祝辞,arr [child +, 1]) { 孩子+ +,//保证是孩子结点最大的一个节点 }//交换 if (arr(孩子),& lt;, arr(父)) { 交换(arr(孩子),arr(父)); 时间=parent 儿童; 时间=child 2, *, parent +, 1; } 其他的 { 打破; } } } int *,找到(int *加勒比海盗,int k, int N) { 断言(arr); 断言(k 祝辞,0); int * str =, new int [k];//把前k个元素放在堆中 for (int 小姐:=,0;,小姐:& lt;, k;,我+ +) { str[我],=,arr[我]; }//调成最小堆 for (int j =, (k 安康;2),/,2,,j 祝辞=,0;,j——) { _AdjustDown (str, j, k); }//然后k到N的所有数与堆中的根结点相比较 时间=for (int n k;, n & lt;, N;, N + +) { if (str [0], & lt;, arr [n])//如果根结点小于堆中k到n中的某一元素 { str [0],=, arr [n];//把这个元素赋值给根结点 _AdjustDown (str, 0,, k);//再一次调成最小堆 } } return str; 删除[]str; }
,希望这个对你们有帮助。期待你们的回复,有什么不对的地方可以指出来啊。