堆是一种经过排序的树形数据结构,每个结点都有一个值。通常我们所说的堆的数据结构,是指二叉堆。堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。由于堆的这个特性,常用来实现优先队列,并用于一些图论算法中。堆也用于排序算法,如堆排序。
二叉堆是一种特殊的堆,二叉堆是完全二叉树或者是近似完全二叉树。二叉堆满足堆特性:父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值,且每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。 当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。
实例如下:
1 11
/ / / /
2 3 9 10
/ / / / / / / /
4 5 6 7 5 6 7 8
/ / / / / / / /
8 9 10 11 1 2 3 4
二项堆(binomial heap)是一种类似于二叉堆的堆结构。与二叉堆相比,其优势是可以快速合并两个堆。
二项树:是一种递归定义的有序树,定义如下:
1.度数为0的二项树只包含一个节点
2.度数为k的二项树只有一个根节点,根节点有k个子女,每个子女分别是度数k-1, k-2,...,2,1,0的二项树的根。
实例如下:
度数为k的二项数共有2k个结点,高度为k。在深度d处有(二项式系数)个结点。
二项堆:二项堆是指满足下列性质的二项树的集合:
1.每棵二项树都满足最小堆性质,即节点关键字大于等于其父节点的关键字。
2.不能有两颗或以上的二项树有相同度数
二项堆的合并操作
最基本的为二个度数相同的二项树的合并:由于二项树根结点包含最小的关键字,因此在二颗树合并时,只需比较二个根结点关键字的大小,其中含小关键字的结点成为结果树的根结点,另一棵树则变成结果树的子树。
两个二项堆的合并则可按如下步骤进行:度数j从小取到大,在两个二项堆中如果其中只有一棵树的度数为j,即将此树移动到结果堆,而如果只两棵树的度数都为j,则根据以上方法合并为一个度数为j + 1的二项树。此后这个度数为j + 1的树将可能会和其他度数为j + 1的二项树进行合并。
此操作的时间复杂度为O(logn)。
二项堆其他操作:
以下对于二项堆操作的运行时间都为O(logn)(结点数为n):
- 在二项堆中插入新结点
- 查找最小关键字所在结点
- 从二项堆中删除最小关键字所在结点
- 减小给定结点关键字的值
- 删除给点结点
- 合并两个二项堆