1:左子樹結點=父節點2+1 右子樹結點=父節點2+2
已經知道孩子結點是i。則父節點是(i-1)/2.
2:堆其實就是一顆完全二叉樹,儲存在數組中,主要是為了找到數組中的最值。分為大堆和小堆
3:向下調整:以大堆為例:找到最後一課子樹的根節點,然後比較根節點和子節點的值,誰大放到根節點,然後父節點在指向被換的子節點,繼續判斷。小堆的話 從最上面開始比較,比較根和左右的大小,誰小就放在根,然後根指向被換的子節點。
4:堆的應用:入堆:向上調整。以大堆為例,誰大就放在根節點,然後讓孩子等于父親,父親繼續往上。
出堆:向下調整。直接讓第一個數字和最後一個數字交換位置,然後向下調整,長度減一。
5:一個一個出堆:一直重複交換第一個和最後一個元素,然後向下調整,長度減一。每調整一次結束,就繼續重複,繼續長度減去一,這樣就都出堆了。
6:TOPK問題
TOPK問題 100萬個資料中 去找前10個最大的或者前10個最小的1;建堆 找最大 就開始建大小為10的小堆,從第11個開始,每個資料和目前堆頂元素比較,如果比堆頂元素大,那麼堆中的元素出隊,然後把目前元素放進這個堆裡。
求前10個最小的就建一個大堆
求前10個最大的就建一個小堆
這種問題的思路:1:先建立一個大堆。代碼:
PriorityQueue maxHeap=new PriorityQueue<>(k, new Comparator() {
public int compare(Integer o1, Integer o2) {
return o2-o1;//大堆就是o2-o1
}
});
此時大堆的代碼已經建立好了,要注意引用Comparator
2:周遊整個數組,看看前10個數字是否填滿,沒有就先填滿。
3:滿了就讓第11個數字與根比較,如果i第11個值小,就與根結點交換。