拿到這個題目我想到了很多方法,但是在我想到的方法中,要把在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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。