概述
堆是一种完全二叉树,分为两种类型:
大顶堆:每一个非叶子结点均不小于其孩子结点。
小顶堆:每一个非叶子结点均不大于其孩子结点。
堆中根结点的位置称为堆顶,最后结点的位置称为堆尾,结点个数称为堆长度。由于结点从1开始编号,所以堆尾的结点编号等于其堆长度。
堆有以下特性:
a.对于大顶堆,堆顶元素是最大值。对于小顶堆,堆顶元素是最小值。
b.对于大顶堆,堆顶的左右孩子结点中元素值较大的为第二大值。对于小顶堆,堆顶的左右孩子结点中元素值较小的为第二小值。
堆的特性常被用于实现排序。
堆
堆常用的操作有:
插入:在堆尾后插入新结点。
修改:修改某个结点的元素值,然后调整堆结构。
删除:将某个结点与堆尾交换,然后删除堆尾,最后调整堆结构。
堆接口的定义如下:

1 /** 2 * 堆 3 */ 4 public interface Heap<E extends Comparable<E>> { 5 6 /** 7 * 堆类型 8 */ 9 enum Tag { 10 /** 11 * 大顶堆 12 */ 13 GREAT, 14 15 /** 16 * 小顶堆 17 */ 18 LESS; 19 } 20 21 /** 22 * 添加结点 23 * @param e 24 */ 25 void add(E e); 26 27 /** 28 * 修改指定结点的元素值,并重新调整 29 * @param index 30 * @param e 31 * @throws HeapException 32 */ 33 void set(int index, E e) throws HeapException; 34 35 /** 36 * 删除指定结点的元素值 37 * @param index 38 * @throws HeapException 39 */ 40 void remove(int index) throws HeapException; 41 42 /** 43 * 判断是否为空堆 44 * @return 45 */ 46 boolean isEmpty(); 47 48 /** 49 * 获取堆中元素个数 50 * @return 51 */ 52 int getNum(); 53 54 /** 55 * 判断是否为大顶堆 56 * @return 57 */ 58 boolean isGreatHeap(); 59 60 /** 61 * 判断是否为小顶堆 62 * @return 63 */ 64 boolean isLessHeap(); 65 66 }
其抽象类定义如下:

1 public abstract class AbstractHeap<E extends Comparable<E>> implements Heap<E> { 2 3 /** 4 * 堆长度 5 */ 6 protected int num; 7 8 /** 9 * 堆类型 10 */ 11 protected Tag tag; 12 13 /** 14 * 计算父结点编号 15 * @param index 16 * @return 17 */ 18 protected int getParentIndex(int index) { 19 return index % 2 == 0 ? index / 2 : (index - 1) / 2; 20 } 21 22 /** 23 * 计算左子结点编号 24 * @param index 25 * @return 26 */ 27 protected int getLchildIndex(int index) { 28 return 2 * index; 29 } 30 31 /** 32 * 计算右子结点编号 33 * @param index 34 * @return 35 */ 36 protected int getRchildIndex(int index) { 37 return 2 * index + 1; 38 } 39 40 /** 41 * 检查是否为空堆 42 * @throws HeapException 43 */ 44 protected void checkEmpty() throws HeapException { 45 if (isEmpty()) throw new HeapException("堆中没有元素!"); 46 } 47 48 /** 49 * 检查编号是否超出范围 50 * @param index 51 * @throws HeapException 52 */ 53 protected void checkOutOfBounds(int index) throws HeapException { 54 checkEmpty(); 55 if (index < 1) throw new HeapException("编号" + index + "必须为正数!"); 56 if (index > num) throw new HeapException("编号" + index + "超出范围!"); 57 } 58 59 @Override 60 public boolean isEmpty() { 61 return num == 0; 62 } 63 64 @Override 65 public int getNum() { 66 return num; 67 } 68 69 @Override 70 public boolean isGreatHeap() { 71 return tag == Tag.GREAT; 72 } 73 74 @Override 75 public boolean isLessHeap() { 76 return tag == Tag.LESS; 77 } 78 79 }
堆的存储结构分为顺序存储和链式存储。
顺序存储结构如下:
链式存储结构如下: