① 對是一個徹底二叉樹 ; ② 堆中的每一個節點的值都必須 >=(或者<=)其子樹中每一個節點。算法
插入徹底二叉樹中,也就是插入到數組的最後一個位置。 api
此時破壞了堆的特性,須要調整(也叫堆化):① 從下往上 比較交換直到符合規則數組
② 從上往下比較交換直到符合規則緩存
堆的插入刪除操做都是順着節點路徑比較交換,徹底二叉樹的高度log2n,所以時間複雜度O(logn)bash
藉助堆結構的特色,把數組中數據位置對應到堆上對應位置,經過調整堆來對數組中數據進行排序。ui
對一組數據進行堆排序(以大頂堆爲例)。spa
private static void buildHeap(int[] a, int n) {
for (int i = n/2; i >= 1; --i) {// 它是徹底二叉樹,所以有子節點的父節點i向上確定都是父節點
heapify(a, n, i);
}
}
private static void heapify(int[] a, int n, int i) {
while (true) { // 交換後節點下邊的子樹又須要從新刷新位置
int maxPos = i;
if (i*2 <= n && a[i] < a[i*2]) maxPos = i*2;
if (i*2+1 <= n && a[maxPos] < a[i*2+1]) maxPos = i*2+1;
if (maxPos == i) break;
swap(a, i, maxPos);
i = maxPos;
}
}
複製代碼
// n 表示數據的個數,數組 a 中的數據從下標 1 到 n 的位置。
public static void sort(int[] a, int n) {
buildHeap(a, n);
int k = n;
while (k > 1) {
swap(a, 1, k);
--k;
heapify(a, k, 1);
}
}
複製代碼
空間複雜度O(n)code
時間複雜度O(nlogn)cdn
不穩定排序blog
堆的排序過程當中,每次都會找出剩餘元素中最大的元素,所以能夠應用於求topN