您好,登錄后才能下訂單哦!
拿到這個題目我想到了很多方法,但是在我想到的方法中,要把在100萬個數中找到前k個數,都不適用。最后通過我的不斷研究,我想到了我認為最簡單的方法,就是利用堆來做這道題目。
下面我分析一下我用堆排序的思路:
1.我先建一個大小為k的堆。
2.把100萬中前k個數放到這個堆中。
3.把這個堆調成小堆。
4.把100萬個從k到100萬之間的數字拿出來和堆的根結點作比較。
5.如果根結點小于這之間的某一個數,就把這個數拿給根結點,然后繼續調成小堆。否則繼續找
6.直到找完這100萬個數,堆中放的就是最大的前k個數。
代碼如下:
//下調 void _AdjustDown(int *arr, int parent, int size) { int child = 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, int k,int N) { assert(arr); assert(k > 0); int *str = new int[k]; //把前k個元素放在堆中 for (int i = 0; i < k; i++) { str[i] = arr[i]; } //調成最小堆 for (int j = (k - 2) / 2; j >= 0; j--) { _AdjustDown(str, j, k); } //然后k到N的所有數與堆中的根結點相比較 for (int n = k; n < N; n++) { if (str[0] < arr[n])//如果根結點小于堆中k到N中的某一元素 { str[0] = arr[n];//把這個元素賦值給根結點 _AdjustDown(str, 0, k);//再一次調成最小堆 } } return str; delete[]str; }
希望這個對你們有幫助。期待你們的回復,有什么不對的地方可以指出來啊。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。