二项堆的合并操作比二叉堆的合并操作复杂度要低,个人觉得二项堆比较难理解,现借此把学习二项堆的笔记写下,这个知识点本人理解的还是不够透彻,希望得到大家的指教。
因为二项堆是一组二项树的集合,学习二项堆时,需要用到二项树的知识点,在这里先讲解下二项树的概念和一些性质。
二项树
定义
二项树采用的是递归定义的有序树,二项树B0只包含一个结点,二项树Bk由两颗二项树Bk-1链接而成:其中一棵树的根是另一棵树的根的最左孩子。
二项树Bk的性质
1) 共有2k个结点
2) 树的高度为k
3) 在深度i处恰有Cik个结点,其中i=0,1,...,k
4) 根的度数(子女的个数)为k,它大于任何其他结点的度数;如果根的子女从左到右的编号设为k-1, k-2, …, 0,子女i是子树Bi的根。
二项树的结构
二项堆
二项堆定义
二项堆H由一组满足以下性质的二项树组成:
1) H中的每个二项树都遵循最小堆性质:节点的关键字不大于其子节点的关键字。因此,根的关键字最小
2) 对任意非负整数k,在H中至多有一棵二项树的根具有度数k。
二项堆存储结构
二项堆的操作
关于二项堆的操作,很多资料给出来伪代码,读者可以根据对伪代码的理解自己编写出源程序,为了方便以后查看,现把个人在参考资料中看到的伪代码附在下面:
1、返回最小关键字节点
由于二项堆中每个二项树都是遵循最小堆性质的,所以最小关键字一定是在根表中,遍历根表一次即可找出最小元素:
BINOMIAL-HEAP-MINIMUM(H)
y=NIL
x = head[H]
min<- ∞
while x!= NIL
do if key[x] < min
then min key[x]
y<- x
x <- sibling[x]
return y
2、合并两棵根节点度数相同的二项树
BINOMIAL-LINK(y,z)
p[y] <- z
sibling[y] <- child[z]
child[z] <- y
degree[z] <- degree[z]+1
3、将H1和H2的根表合并成一个按度数的单调递增次序排列的链表
BINORMIAL-HEAP-MERGE(H1,H2)
head(H)=NULL
x=head(H1)
y=head(H2)
if(x==NULL)
return y
if(y==NULL)
return x
if(degree(x)<degree(y))
head(H)=x
x=sibling(x)
els