堆的定義
-
堆是一個完全二叉樹,這樣的堆也被稱爲二叉堆。(之前瞭解過相關知識,但是現在大部分忘記了。後續博客上會補充上去)
-
子節點大於如果大於節點,這樣的堆稱爲小頂堆。子節點小於節點的堆稱爲大頂堆。
堆的基本操作有插入、刪除堆頂元素。
堆的操作圖解
- 堆化。將堆中的元素重新按照堆的結構插入,類似於排序。
-
刪除堆頂元素。將堆頂的元素刪除,再將堆進行堆化。(其中,如果出現了數組空洞,可以將最後一個元素覆蓋堆頂元素,再執行堆化)
在平時代碼中的應用
可能是因爲我瞭解的太少,感覺用處不是很大,因爲基礎的工具對於這些數據的操作大部分都已經封裝好了,只需要知道怎麼調用就可以了。但是作爲程序員來說,知道其內部原理還是比較好的。
因爲很長時間沒有學習數據結構了,所以這個寫着相當費力,後面陸續會寫相關博客,但是可能不是很多。。。
代碼在下面。註釋中對於代碼的解釋已經很詳細了。
package arraytrain;
/**
* HeapTrain.java
* Description: 堆的練習
*
* @author Peng Shiquan
* @date 2020/5/2
*/
public class HeapTrain {
private int[] arr;
/**
* 堆內當前堆元素
*/
private int n;
/**
* 堆內最大堆元素
*/
private int capacity;
/**
* Description:初始化
*
* @param count
* @return
* @Author: Peng Shiquan
* @Date: 2020/5/2
*/
public HeapTrain(int count) {
capacity = count;
arr = new int[capacity + 1];
n = 0;
}
public void heapPrint() {
for (int i = 0; i < n + 1; i++) {
System.err.print("[" + arr[i] + "]");
}
}
/**
* Description: 換位方法
*
* @param a
* @param b
* @return void
* @Author: Peng Shiquan
* @Date: 2020/5/2
*/
public void swap(int a, int b) {
int swap = arr[a];
arr[a] = arr[b];
arr[b] = swap;
}
/**
* Description:向堆中插入元素
*
* @param value
* @return void
* @Author: Peng Shiquan
* @Date: 2020/5/2
*/
public void insert(int value) {
if (n >= capacity) {
return;
}
n++;
arr[n] = value;
int i = n;
/**
* 兩個判斷條件,一個是i是不是標號最小的元素、節點是不是大於子節點
*/
while (i / 2 > 0 && arr[i / 2] < arr[i]) {
swap(i / 2, i);
i = i / 2;
}
}
/**
* Description:刪除堆頂元素
*
* @param
* @return void
* @Author: Peng Shiquan
* @Date: 2020/5/2
*/
public void deleteMax() {
if (n == 0) {
}
int tmp = arr[1];
/**
* 堆內可以放負數,如果arr[1]=0,負數就沒法比較
*/
int count = n;
/**
* 將最後的元素放到跟節點,防止數組空洞。同時將兩步堆化合併爲一步
*/
arr[1] = arr[count];
n--;
heaply(1, n);
}
/**
* Description: 堆化處理
*
* @param index
* @param n
* @return void
* @Author: Peng Shiquan
* @Date: 2020/5/2
*/
public void heaply(int index, int n) {
while (true) {
/**
* 默認當前節點是最大節點
*/
int maxValueIndex = index;
/**
* 先計算左節點
*/
if (maxValueIndex * 2 <= n && arr[maxValueIndex] < arr[maxValueIndex * 2]) {
maxValueIndex = maxValueIndex * 2;
}
/**
* 計算右節點
*/
if (maxValueIndex * 2 + 1 <= n && arr[maxValueIndex] < arr[maxValueIndex * 2 + 1]) {
maxValueIndex = maxValueIndex * 2 + 1;
}
/**
* 經過比較確實是最大節點
*/
if (maxValueIndex == index) {
break;
}
swap(index, maxValueIndex);
/**
* 把最大節點給到當前節點的子節點
*/
index = maxValueIndex;
}
}
public static void main(String[] args) {
HeapTrain heapTrain = new HeapTrain(10);
heapTrain.insert(3);
heapTrain.insert(1);
heapTrain.insert(9);
heapTrain.heapPrint();
System.err.println();
heapTrain.deleteMax();
heapTrain.heapPrint();
}
}