實現堆的插入和刪除操作
阿新 • • 發佈:2019-07-09
最大堆的插入
//向最大堆中插入元素, 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);