1、最小堆
/*
* 最小堆:解決Top k的問題,例如 得到數組中第k大的數
* 存儲結構:實際上是一數組
* 幾個重要的操作:
* 1、buildHeap將普通的數組轉化爲堆(所有父節點的值小於或者等於兩個節點的值)
* 2、heapify(int i):當元素i的左右子樹都是小根堆時,通過heapify讓i元素下降當適當的位置,以符合堆的性質
*/
public class MinHeap {
private int[] data;//基本結構
public MinHeap(int[] data) {
this.data = data;
buildHeap();//創建最小堆
}
private void buildHeap() {
/*
* 完全二叉樹只有數組小標小於或等於(data.length)/2 -1的元素有孩子節點
*/
for(int i = data.length / 2 -1;i>=0;i--) {
//對有孩子節點的元素heapify
heapify(i);
}
}
private void heapify(int i) {
//獲取左右節點的數組下標:除數組第一個元素,其餘元素將按照順序2個分爲1組,第一個節點的左右節點對應第一組元素,第二個節點的左右節點對應第二組元素。。。。
//第i個節點的左右節點數組下標爲 (i+1)*2-1 (i+1)*2
int left = (i + 1) * 2 - 1;
int right = (i + 1) * 2;
int minIndex = i;//最小值的座標
//存在左結點,且左節點的值小於根節點的值
if(left < data.length && data[left] < data[i])
minIndex = left;
//存在右節點,且右節點的子小於以上比較的較小值
if(right < data.length && data[right] < data[minIndex])
minIndex = right;
//若該跟節點就是最小值,那麼不用操作
if(i == minIndex)
return;
//否則進行交換
int temp = data[i];
data[i] = data[minIndex];
data[minIndex] = temp;
//由於替換後的左右子樹會被影響,所有要對受影響的子樹在進行heapify
heapify(minIndex);
}
//獲取較小的元素
public int getMin() {
return data[0];
}
//插入元素
public void insert(int val) {
data[0] = val;
heapify(0);
}
}