面經筆記 堆排序與topk問題

2021-08-03 16:27:19 字數 1108 閱讀 6088

維持堆函式:

h為新元素位置,假設h的兩個孩子樹已經是最大堆

1、 如果d[h]為d[h]、左孩子、右孩子中的最大值,則結束調整。

2、 否則,將x[h]與孩子中的最大值互換,更新h值,返回上一步

void keepheap(int *  array, int len, int h)

if (rightchild < len && array[lagest] < array[rightchild])

if (lagest == h)

else

}

二叉樹使用陣列實現時,節點下標的關係:

如果從下標從1開始儲存,則編號為i的結點的主要關係為:

雙親:下取整 (i/2)

左孩子:2i

右孩子:2i+1

如果從下標從0開始儲存,則編號為i的結點的主要關係為:

雙親:下取整 ((i-1)/2)

左孩子:2i+1

右孩子:2i+2

建堆函式:

自底向上建堆,先對左右子樹建堆,然後對根節點使用維持堆函式

void makeheap(int *  array, int len)

int k = (len - 1) >> 1;

for (auto i = k; i >= 0; --i)//利用keepheap建堆

}

建堆的時間複雜度是多少?

o(n)

堆彈出函式:

將根節點與陣列最後乙個元素互換後,減少堆節點數,重新維護堆

void pop(int *  array,int

len)

堆排序:

先建堆,然後逐個彈出

void heapsort(int * array,int

len)

}

topk問題:

先建立k大小的最小堆

然後每次將新物件值與堆頂比較,如果比堆頂大,則用新值替換堆頂,並重新維持堆

堆排序與topK問題

找出乙個有10億數字陣列中,前k個最大值 第一步 hash去重 解法1 劃分法 def partition l,left,right low left if left right key l left high right while low high while low high and l hi...

堆排序 TOPK問題 C

現在有n個數,設計演算法得到前k大的數。k 首先從原列表擷取前k個元素,組成乙個新列表。然後將這個新列表構建成乙個小根堆,那麼根就新列表中最小的數。接著繼續從原列表取出k以後的元素,和小根堆根比對,如果比根小,那麼肯定不屬於前k大的數,如果比根大,替換根,然後做一次向下調整,根重新變成新列表最小的數...

堆排序的應用 TOPK問題

我們知道堆有大根堆和小根堆兩種,那麼在解決找堆中k個最大值的問題時應該用大根堆還是小根堆呢?答案是找k個最大的,要建立k大小的小堆。思路如下 比如下面這個陣列,要去取出其中最大的四個值,然後將後面的值與堆頂值比較,若大於堆頂值則彈出堆頂,將新的值加入堆 重複這個步驟,堆中的值會整體增大,陣列遍歷完後...