一、什么是堆?
作为一种数据结构,堆是一个完全二叉树,且堆中每个节点的值必须大于等于(或小于等于)其子节点的值。
- 对于每个节点的值都大于等于其子节点值的堆,称作“大顶堆”。
- 对于每个节点的值都小于等于其子节点值的堆,称作“小顶堆”。
下图为大顶堆。
二、堆的存储方式
堆作为一种完全二叉树,比较适合用数组来存储,这样就不用像二叉树一样,每个节点都要存储左右子节点的指针了。用数组存储只需要通过数组下标,就可以找到当前节点的左右子节点。
如图,数组下标为i的节点,其左子节点的下标为2 * i,右子节点的下标为2 * i + 1,父节点的坐标为 i / 2。
三、堆的基本操作
1、堆的插入
先将需要新节点,以满足完全二叉树特性的方式,插入到堆的最后一层;
对这个堆进行调整,让新插入的节点与父节点进行对比,以大顶堆为例,如果子节点的值大于父节点,则交互两个节点。然后不断地向上调整,最后使得全部节点满足此关系。这个过程通常称为“向上堆化”。
代码实现:
public class Heap{
private int[] a;//数组,下标从1开始存储
private int n;//堆中可以存储的最大数据的个数
private int count;//堆中已存储的数据个数
//构造方法
public Heap(int capacity){
a = new int[capacity+1];
n = capacity;
count = 0;
}
//堆的插入
public void insert(int data){
//判断堆中容量是否充足
if(count >= n){
return;
}
//如果容量充足,就将新元素放到已有数据的后面一位
++count;
a[count] = data;
int i = count;
//向上堆化
while(i/2 >= 1