• 跟我一起学算法——斐波那契堆


    斐波那契堆(Fibonacci Heap)

    1. 定义

    FibHeap是一个树的集合,且树满足最小堆性质。根表不要求树根的度有序,head指向根表中值最小
    的结点。全部使用双向循环链表。
    KEY:防止超出O(lgn)的操作出现,也即防止出现度超过O(lgn)的树出现,只要能保证D(n)<=
    lgn,其性能优于二项堆。

    2. 数据结构

    • 结点的域
      p:父指针
      left,right:左右指针
      key:值
      degree:度
      child:指向任意孩子
      mark:非常重要的标志位。创建结点或结点成为孩子时,mark=false,结点失去一个孩子时,mark=true。
    • 根表以及结点间 双向循环链表

    3. 预定义

    1. 势函数定义
      f(H)=t(H)+2m(H)
      f表示势函数,t表示树的个数,m表示mark=true的结点数。
    2. 平摊分析
      C^i = C_i + f(i) - f(i-1)
      C^i:平摊成本
      C_i:操作的实际成本
      f(i-1):操作前的势能
      f(i):操作后的势能
    3. 任意结点的最大度上界 D(n)
    4. 无序二项树U_k
      不要求按子树的度的大小排列。

    4. 五个基本操作

    1. 创建空堆
    2. 插入结点x
      将x作为U_0树插入根表,检查head, x.mark=false
      平摊分析:
      C_i = O(1)
      f(i)-f(i-1)=t(H')-t(H)+2m(H') -2m(H)=1+0=1
      则C^i=O(1)
    3. 查找最小值结点
      head
      平摊成本O(1)
    4. 合并堆
      step1:合并根表
      step2:检查head
      平摊成本O(1)
    5. 抽取最小值结点z
      平摊成本O(D(n))
    • 将z的子树插入根表
    • delete z, head随意指
    • 清理根表,防止根表过大。合并相同度的树,重构堆,并将head指向最小结点。
      使用一个辅助指针数组A[0,..., D(n[H])],高效合并和重构堆。D(n[H])表示根结点的最大度。
      数组下标表示度,数组元素为根节点指针,初始化为null。合并度相同的树,最终使根表中的度是
      唯一的。
      注意:以head为起点,向右扫描根表,同时合并相同度的二项树,直到根表中的树具有唯一的度。

    5.两个扩展操作

    1. 结点减值
    • 根结点减值后不需要后续操作
    • 非根结点x减值后如果破坏了最小堆性质,则需要后续操作
    • 切断x与其父结点y的关系,把x加入根表,x.mark=Flase
    • 级联切断 递归检查y结点,如果x是它被剪掉的第二个孩子(y.mark=TRUE),则y也从原
      树中脱离,加入根表,同时y=y.p,继续检查,直到y.mark=false或y=root
    • 别忘记重新确定head->min
    fibHeap_decrease(h, x, k):
      if k > x.KEY:
        error
        return
      x.key = k
      y = x.p
      if y is not None and x.key < y.key:
        # 切 x
        cut(h, x, y)
        # 级联切断
        cascading_cut(H, y)
      # 检查head
      if x.key < h.min.key :
        h.min = x
    
    cut(h,x,y):
      remove x from y
      y.degree -= 1
      add x to rootlist
      x.p = None
      # 关键
      x.mark = FALSE
    
    cascading_cut(H, y):
      z = y.p
      if z is not None:
        if y,mark == FALSE:
          y.mark = TRUE
        else :
          cut(H,y,z)
          cascading_cut(H,z)
    
    1. 删除结点
    • x结点减值到MIN
    • 抽取最小值

    参考

    《算法导论》

  • 相关阅读:
    浅谈 PHP 与手机 APP 开发(API 接口开发)
    Thinkphp+Nginx(PHPstudy)下报的404错误,403错误解决
    win7彻底卸载iis
    Java ByteCode 规格严格
    CPUID 规格严格
    Your First Plugin(转载) 规格严格
    SQLYog Enterprise注册码 规格严格
    WSUS API&&WUAPI 规格严格
    linux学习一则 规格严格
    Eclipse分析源代码时总是显示org.eclipse.core.runtime.CoreException错误,找不到***文件(转载) 规格严格
  • 原文地址:https://www.cnblogs.com/ChengzhiYang/p/12402515.html
Copyright © 2020-2023  润新知