二项堆与斐波那契堆

来源:互联网 发布:java工程师培训价格 编辑:程序博客网 时间:2024/06/06 18:21

二项堆

参考
http://blog.csdn.net/chenjiayi_yun/article/details/38347117

定义

二项堆是符合最小堆性质的二项树链接成的森林

二项树是形如下图的树
这里写图片描述
即节点数是2k 的树,且满足Tree[K+1]= Tree[K] + Tree[K]
每个二项树都要求满足最小堆(or 最大堆)性质(即父节点总是小于等于子节点)

将一些度不重复的二项树链接起来就是一个二项堆, 如下图就是一个由Tree[0] + Tree[2] + Tree[3] 共 20+22+23=13个节点组成的二项堆
这里写图片描述

特性

  • min
    由于每个二项树都满足最小堆性质,求最小值的操作只需要遍历连接各个树的节点即可, O(lgN)
  • merge
    合并操作有很好的性质,原因在于两个度相同的二项树合并可以生成一个度+1的二项树,即Tree[k] + Tree[k] = Tree[k+1],只需要选择顶节点值更小的树称为主干就能满足最小堆性质, 所以两个二项堆的合并就像在做二进制加法一样, 最坏O(lgN)
    这里写图片描述
  • add
    添加一个元素就像把原堆和一个只有一个度为0的树的堆进行合并一样,如下图所示连续add, 最坏O(lgN)
    这里写图片描述

斐波那契堆

参考
讲的非常详细 http://www.cnblogs.com/skywang12345/p/3659060.html

类似二项堆,不同的是链表中的每个树不一定是二项树,思路是把复杂操作延后到min操作上,add和merge操作都非常简单

操作图解

  • add
    这里写图片描述

  • merge
    这里写图片描述

  • min_pop
    取最小值操作最复杂,这一步需要整理整个链表
    (1)将要抽取最小结点的子树都直接串联在根表中;
    (2)合并所有degree相等的树,直到没有相等的degree的树。
    * 注:两个最小堆性质的树合并只需要比较顶元素,然后将较大的那个树和较小的树的某个子树递归的进行合并就行可以
    这里写图片描述

  • 减少和增加节点值的操作参看博客 注意防止树退化成链表的操作

原创粉丝点击