二叉堆自己也是個二叉樹,有兩個限制:web
由於徹底二叉樹中,數據排列順序是從上而下,從左至右,因此能夠用數組的形式保存數據。一般根結點做爲數組的 0 號元素,其左右孩子分別是 2 號、3 號元素,以此類推。api
保證一個元素符合要求的過程,能夠叫作 heapify。其順序是:數組
void swap(int tree[], int i, int j) { int tmp = tree[i]; tree[i] = tree[j]; tree[j] = tmp; } void heapify(int tree[], int n, int i) { if (i >= n) { return; } int max = i; int c1 = i * 2 + 1; int c2 = i * 2 + 2; if (c1 < n && tree[i] < tree[c1]) { max = c1; } if (c2 < n && tree[max] < tree[c2]) { max = c2; } if (max != i) { swap(tree, i, max); } heapify(tree, n, c1); heapify(tree, n, c2); }
每次 heapify 能夠確保二叉樹中的最大元素上移一層,因此須要對除最後一層外的全部元素逐個調用 heapify:svg
void heapifyAll(int tree[], int n) { int last = (n - 1) / 2; int i; for (i = last; i >= 0; i--) { heapify(tree, n, i); } }
二叉堆構建完成後,就能夠對其進行排序了。步驟以下:spa
void heapSort(int tree[], int n) { heapifyAll(tree, n); int i; for (i = n - 1; i >= 0; i--) { swap(tree, 0, i); heapify(tree, i, 0); } }
#include <stdio.h> void swap(int tree[], int i, int j) { int tmp = tree[i]; tree[i] = tree[j]; tree[j] = tmp; } // 對單個結點堆化 void heapify(int tree[], int n, int i) { if (i >= n) { return; } int max = i; int c1 = i * 2 + 1; int c2 = i * 2 + 2; if (c1 < n && tree[i] < tree[c1]) { max = c1; } if (c2 < n && tree[max] < tree[c2]) { max = c2; } if (max != i) { swap(tree, i, max); } heapify(tree, n, c1); heapify(tree, n, c2); } // 對整個徹底二叉樹堆化 void heapifyAll(int tree[], int n) { int last = (n - 1) / 2; int i; for (i = last; i >= 0; i--) { heapify(tree, n, i); } } // 堆排序 void heapSort(int tree[], int n) { heapifyAll(tree, n); int i; for (i = n - 1; i >= 0; i--) { swap(tree, 0, i); heapify(tree, i, 0); } } int main(void) { int i; int tree[6] = {3, 2, 5, 4, 7, 1}; // heapify(tree, 6, 1); heapifyAll(tree, 6); printf("堆:\n"); for( i = 0; i < 6; i++) { printf("%d\n", tree[i]); } heapSort(tree, 6); printf("新順序:\n"); for( i = 0; i < 6; i++) { printf("%d\n", tree[i]); } return 0; }