博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
斐波那契堆
阅读量:4154 次
发布时间:2019-05-25

本文共 1163 字,大约阅读时间需要 3 分钟。

今天看斐波那契堆看的头昏脑胀,原因是书上写的太乱了。。。

看到网友写的就很不错

由于增加了删除和关键字减值操作,所以,F堆中的最小树就不一定必须是二项树了。事实上,可能存在度为k却只有k + 1(原书是k + 1,应该是k – 1吧)个结点的最小树。为了保证每个度为k的最小树至少包含ck个结点(c > 1), 每次执行删除操作和关键字减值操作后,还必须进行级联剪枝操作。为此,为每个结点增加一个布尔类型的child_cut域(即本文里的marked)。child_cut域的值仅对那些不是最小树树根的结点有意义。对于不是最小树树根的结点x, x的child_cut域为TRUE,当且仅当在最近一次x成为其当前父结点的儿子之后,x的一个儿子被删除。这就意味着,在执行删除最小元素中,每次连接两棵最小树时,关键字值较大的根结点的child_cut域应该赋值为FALSE。更进一步地说,一旦删除操作或关键字减值操作将最小树的非根结点q从其所在双向链表中删除时,则调用级联剪枝操作。在执行级联剪枝操作过程中,检查从被删除结点q的父节点p开始,到被删节点的最近的child_cut域为FALSE的祖先结点的路径。对在该路径上所有child_cut域为TRUE的非根结点,将其从所在的双向链表中删除,并将其加入到F堆的最小树的根节点组成的双向链表中。如果该路径上存在child_cut域为FALSE的结点 ,则将其该域的值修改为TRUE。

 级联剪切的过程很明了,我当时看的时候最烦的问题是,为什么要进行级联剪切,级联剪切丫的要干什么? 

     如果仅仅要切除父结点y的一个结点x,则仅仅需要把结点x加入到根结点所在双向链表中,再检测y是否marked == true即可,这是因为斐波那契中的树并不一定是二项树,近似二项树也可以。当删除y的第二个结点时,对在该路径上所有marked域为TRUE的非根结点,将其从所在的双向链表中删除,并将其加入到F堆的最小树的根节点组成的双向链表中,即只有在删除同一个结点偶数个孩子时,才要进行级联剪枝,来维护二项树性质,奇数个时(即一个),对树影响不大,莫管它,只标记一下即可。

      为什么偶数个的时候要递归往上删除?

     二项树中在深度为i处恰有Cik个结点(I = 0, 1, 2, ……, k)。试着如果不进行级联剪枝,就可以发现,稍微删得结点超过两三个,最后的树就会不成样子,毫无章法。但是如果进行了级联剪枝,在偶数个结点时进行级联剪切时,原来是C30 = 1, C3= 3, C3= 3, C3= 1, 减少两个结点关键字后,变为:C2= 0,C21 = 2, C22 = 1;二项式是对称的,所以,偶数个结点时进行级联剪枝可以保证类似上边的正好使二项式减少一个数量级。

明天附上实现的程序

转载地址:http://cdeti.baihongyu.com/

你可能感兴趣的文章
实验5-6 do-while循环结构
查看>>
实验5-7 程序调试入门
查看>>
实验5-8 综合练习
查看>>
第2章实验补充C语言中如何计算补码
查看>>
深入入门正则表达式(java) - 命名捕获
查看>>
使用bash解析xml
查看>>
android系统提供的常用命令行工具
查看>>
【Python基础1】变量和字符串定义
查看>>
【Python基础2】python字符串方法及格式设置
查看>>
【Python】random生成随机数
查看>>
【Python基础3】数字类型与常用运算
查看>>
【Python基础4】for循环、while循环与if分支
查看>>
【Python基础6】格式化字符串
查看>>
【Python基础7】字典
查看>>
【Python基础8】函数参数
查看>>
【Python基础9】浅谈深浅拷贝及变量赋值
查看>>
Jenkins定制一个具有筛选功能的列表视图
查看>>
【Python基础10】探索模块
查看>>
【Python】将txt文件转换为html
查看>>
[Linux]Shell脚本实现按照模块信息拆分文件内容
查看>>