二叉堆自己也是个二叉树,有两个限制: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; }