最大堆的插入
//向最大堆中插入元素, heap:存放堆元素的數組
public static void insert(List<Integer> heap, int value) {
//在數組的尾部添加
if(heap.size()==0)
heap.add(0);//數組下標爲0的位置不放元素
heap.add(value);
//開始上升操做
// heapUp2(heap, heap.size() - 1);
heapUp(heap, heap.size() - 1);
}
//上升,讓插入的數和父節點的數值比較,當大於父節點的時候就和父節點的值相交換
public static void heapUp(List<Integer> heap, int index) {
//注意因爲數值是從下標爲1開始,當index = 1的時候,已是根節點了
if (index > 1) {
//求出父親的節點
int parent = index / 2;
//獲取相應位置的數值
int parentValue = (Integer) heap.get(parent);
int indexValue = (Integer) heap.get(index);
//若是父親節點比index的數值小,就交換兩者的數值
if (parentValue < indexValue) {
//交換數值
swap(heap, parent, index);
//遞歸調用
heapUp(heap, parent);
}
}
}
最大堆的刪除
/**
* 刪除堆中位置是index處的節點
* 操做原理是:當刪除節點的數值時,原來的位置就會出現一個孔
* 填充這個孔的方法就是,把最後的葉子的值賦給該孔,最後把該葉子刪除
* @param heap
*/
public static void delete(List<Integer> heap,int index) {
//把最後的一個葉子的數值賦值給index位置
heap.set(index, heap.get(heap.size() - 1));
//下沉操做
//heapDown2(heap, index);
heapDown(heap, index);
//把最後一個位置的數字刪除
heap.remove(heap.size() - 1);
}
/**
* 遞歸實現
* 刪除堆中一個數據的時候,根據堆的性質,應該把相應的位置下移,才能保持住堆性質不變
* @param heap 保持堆元素的數組
* @param index 被刪除的那個節點的位置
*/
public static void heapDown(List<Integer> heap, int index) {
//由於第一個位置存儲的是空值,不在考慮以內
int n = heap.size() - 2;
//記錄最大的那個兒子節點的位置
int child = -1;
//2*index>n說明該節點沒有左右兒子節點了,那麼就返回
if (2 * index > n) {
return;
} //若是左右兒子都存在
else if (2 * index < n) {
//定義左兒子節點
child = 2 * index;
//若是左兒子小於右兒子的數值,取右兒子的下標
if ((Integer) heap.get(child) < (Integer) heap.get(child + 1)) {
child++;
}
}//若是隻有一個兒子(左兒子節點)
else if (2 * index == n) {
child = 2 * index;
}
if ((Integer) heap.get(child) > (Integer) heap.get(index)) {
//交換堆中的child,和index位置的值
swap(heap, child, index);
//完成交換後遞歸調用,繼續降低
heapDown(heap, child);
}
}