1、堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:
Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]
或者Key[i]>=Key[2i+1]&&key>=key[2i+2]
即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字。
2、堆分为大顶堆和小顶堆,满足Key[i]>=Key[2i+1]&&key>=key[2i+2]称为大顶堆,
满足 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]称为小顶堆。
由上述性质可知大顶堆的堆顶的关键字肯定是所有关键字中最大的,小顶堆的堆顶的关键字是所有关键字中最小的。
3、构建堆的过程:
public class CreateHeap { public static void main(String[] args) { Integer[] array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; int len = array.length; CreateHeap.buildMaxHeap(array); for (int j = 0; j < len; j++) { System.out.println(array[j]); } } private static void buildMaxHeap(Integer[] a) { for (int i = (a.length - 1) / 2; i >= 0; i--) { maxHeapify(a, i, a.length); } } //构建大顶堆 private static void maxHeapify(Integer[] a, int i, int length) { //i 表示当前父节点 int l = left(i);//左孩子 int r = right(i);//右孩子 int largest = i;//指向最大的节点 while (true) { //左孩子和父节点比较 if (l < length && a[l] > a[i]) { largest = l; } //右孩子和父节点比较 if (r < length && a[r] > a[largest]) { largest = r; } //交换数据 if (i != largest) { swap(a, i, largest); } else { System.out.println(); break; } //交换之后 要重新调整堆满足堆规则 i = largest; l = left(largest); r = right(largest); } } private static void swap(Integer[] a, int i, int largest) { int temp = a[i]; a[i] = a[largest]; a[largest] = temp; } private static int left(int i) { return 2 * i + 1; } private static int right(int i) { return 2 * i + 2; } }
4、堆排序,其实堆排序任然是构建堆的过程:
for (int i = 0; i < len; i++) { temp = array[0]; array[0] = array[len - 1 - i]; array[len - 1 - i] = temp; CreateHeap.maxHeap(array, 0, len - 1 - i); }