优先队列之二项队列(JAVA实现)

一、定义

1.二项树

  • 堆性:每个结点都比它的左右子树中结点要小(小顶堆)
  • 高度为 k 的二项树B(k)通过将一棵二项树B(k-1)附到另一棵二项树B(k-1)的根上构成。而B(k-1)又可以由B(k-2)附到另一棵B(k-2)的二项树上,故:B(k)是由一个根节点和B(0)、B(1)、B(2)….B(k-1)组成的。

如下是二项树B(0),B(1),B(2),B(3),B(4).
这里写图片描述

图1-1

2.二项队列

  • 二项队列不是一棵树,它是一个森林,一个由一组二项树组成的深林。
  • 二项队列中的树高度不同,一个高度至多存在一棵二项树。将高度为0的二项树记为 B(0),高度为 k 的二项树记为 B(k)。即:也就是说,对于k>=0,二项队列中至多存在一棵 B(k)的二项树。
  • 具有N个结点的二项队列最多有 logN 棵二项树。
每棵二项树B(k)中含有2^k个结点。故:
2^0 + 2^1 + 2^2 + .... + 2^k = N,得到 k=logN(k为树的棵数)。注意到上面提到的是“**最多**” 有logN 棵二项树,这说明一个二项队列可以缺少某棵 B(i) , 0<=i<=k
  • 由于二项树中结点个数的性质(B(k)有2^k个结点),而二项队列又是若干二项树的集合,故二项队列可以采用二进制数来标记:
如,大小为13(共有13个结点)的二项队列可以用森林 B(3)B(2)B(0)表示,并可以把这种表示写成 1101,1101以二进制形式表示13,而且还表示了该二项队列中,不存在B(1)这样的树。

二、二项队列的存储结构

二项队列是存储于一个一维数组中,该数组中的每个元素存储一棵二项树的根结点指针。具体存储方式如下图(源于网上)
这里写图片描述

图2-1

该存储方式的特点:

  1. 最右边的那个数组元素存储了一颗高度为0的二项树B(0)。B(0)只有一个结点,该结点的权值为13。如果数组的长度表示二进制的位数,那么这个二项队列表示为 00001101。这说明该二项队列不存在高度为7、6、5、4、1 这样的二项树:B(7)、B(6)、B(5)、B(4)、B(1)。
  2. 二项树在数组中存储是按高度排序的。
  3. 数组第 i 号索引处,存储的是高度为 i 的二项树。如,第0号索引,存储高度为0的二项树,该二项树只有一个结点,结点权值为13
  4. 二项树的采用的是链表表示,这里采用的是“左孩子右兄弟”表示法。(具体表示如下图描述的是B(4)采用左孩子右兄弟表示法)
    这里写图片描述
    图2-2

三、实现思路

1.合并(merge)
假设需要合并二项队列H1和H2,合并后的结果为H3。合并两个二项队列的过程如下:

  • a.寻找H1和H2中高度相同的二项树,合并这两颗二项树
  • b.重复 a) 直至树中不再有高度相同的二项树为止。
  • c.形成了新的二项队列H3

下图(图片源自网上)直观描述了H1和H2合并成H3’的过程。
这里写图片描述

图3-1

下图(图片源自网上)展示将两个相同高度的二项树合并的过程。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值