資料結構和演算法-堆

littlexiaoshuishui發表於2020-06-15

一種特殊的樹,滿足下面兩個條件:

1.堆總是一棵完全二叉樹(除了最後一層,其他都是滿節點,最有一層先排左節點)

2.堆中某個節點的值總是大於等於(小於等於)其所有子節點的值。如果是大於等於情況就稱為大頂堆,小於等於情況就是小頂堆。

完全二叉樹適合用陣列儲存,因為下標為i的元素,它的左子樹下標為2i,右子樹下標為2i+1。父節點就是i/2的overflow。

插入一個元素

先插入的元素放到堆最後,然後和父節點比較,如果大於父節點,就交換位置,然後再和父節點比較,直到把這個元素放到正確的層。這種也叫自下而上的堆化。

刪除一個元素

假如刪除大頂堆的,刪除最大的元素,然後再它的子節點找到第二大元素,放到堆頂。然後再第二大元素下一層尋找

堆排序

比如有n個資料,我們先把資料建堆,生成一個大頂堆,元素個數為n

獲取堆頂資料(也就是最大元素),刪除堆頂,並且把最後一個元素放到堆頂,然後堆化成(n-1)大頂堆

重複獲取堆頂,堆化成(n-2)大頂堆。我們獲取的資料就是從大到小的順序。

堆的應用

應用1:優先順序佇列

合併多個有序小檔案 把多個有序的小檔案的第一個元素取出,放入堆中,取出堆頂到大檔案,然後再從小檔案中取出一個加入到堆,這樣就把小檔案的元素合併到大檔案中了。

應用2:用堆求 Top K(就是從一堆資料中找出前k大的資料)

a. 針對靜態資料(資料不變) 建立大小為K的小頂堆,遍歷陣列,陣列元素與堆頂比較,比堆頂大,就把堆頂刪除,並插入該元素到堆 b. 針對動態資料(資料不斷插入更新的) 在動態資料插入的時候就與堆頂比較,看是否入堆,始終維護這個堆,需要的時候直接返回,最壞O(n*lgK)

應用3:海量關鍵詞搜尋記錄,求搜尋次數topK

a.先用hashTable去重,並累加搜尋次數

b.再建立大小為K的小頂堆,遍歷雜湊表,次數大於堆頂的,頂替堆頂入堆(就是應用2的解法)

雜湊表很大時,超出記憶體要求

  • 建立n個空檔案,對搜尋關鍵詞求雜湊值,雜湊值對n取模,得到該關鍵詞被分到的檔案號(0到n-1)

  • 對每個檔案,利用雜湊和堆,分別求出topK,然後把n個topK(比如10個Top 20,200很小了吧)放在一起,出現次數最多的K(20)個關鍵詞就是這海量資料裡搜尋最頻繁的。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章