維持堆函式:
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大小的小堆。思路如下 比如下面這個陣列,要去取出其中最大的四個值,然後將後面的值與堆頂值比較,若大於堆頂值則彈出堆頂,將新的值加入堆 重複這個步驟,堆中的值會整體增大,陣列遍歷完後...