堆及其应用
一.堆的定义
1.完全二叉树
如果一棵深度为K二叉树,1至k-1层的结点都是满的,即满足2i-1,只有最下面的一层的结点数小于2i-1,并且最下面一层的结点都集中在该层最左边的若干位置,则此二叉树称为完全二叉树。
2.堆结构是一种数组对象,它可以被视为一棵完全二叉树。树中每个结点与数组中存放该结点中值的那个元素相对应。
二.堆的性质
设数组A的长度为len,二叉树的结点个数为size,size≤len,则A[i]存储二叉树中编号为i的结点值(1≤i≤size),而A[size]以后的元素并不属于相应的堆,树的根为A[1],并且利用完全二叉树的性质,我们很容易求第i个结点的父结点(parent(i))、左孩子结点(left(i))、右孩子结点(right(i))的下标了,分别为:i/2、2i、2i+1;
堆具有这样一个性质,对除根以外的每个结点i,A[parent(i)]≥A[i]。这种堆又称为“大根堆”;反之,对除根以外的每个结点i,A[parent(i)]≤A[i]的堆,称为“小根堆”。
三.堆的操作
用堆的关键部分是两个操作:put操作,即往堆中加入一个元素;get操作,即从堆中取出并删除一个元素。
1、往堆中加入一个元素的算法(put)如下:
(1)在堆尾加入一个元素,并把这个结点置为当前结点。
(2)比较当前结点和它父结点的大小
如果当前结点小于父结点,则交换它们的值,并把父结点置为当
前结点。转(2)。
如果当前结点大于等于父结点,则转(3)。
(3)结束。
2、从堆中取出并删除一个元素的算法(get)如下:
(1)取出堆的根结点的值。
(2)把堆的最后一个结点(len)放到根的位置上,把根覆盖掉。把堆的长度减一。
(3)把根结点置为当前父结点pa。
(4)如果pa无儿子(pa>len/2),则转(6);否则,把pa的两(或一) 个儿子中值最小的那个置为当前的子结点son。
(5)比较pa与son的值,如果fa的值小于或等于son,则转(6);否则,交换这两个结点的值,把pa指向son,转(4)。
(6)结束。