【问题标题】:Maintaining Heap Property维护堆属性
【发布时间】:2018-05-19 20:43:50
【问题描述】:
  • 背景简介:我正在研究插入发生时维护堆属性的步骤。这是一个有趣的问题:

  • 问题:有两种通用策略可用于维护堆属性:

    1. 确保树是完整的,然后修复排序或
    2. 先确保顺序正确,然后检查完​​整性。

哪个更好(1 或 2)?

参考:http://www.cs.sfu.ca/CourseCentral/225/johnwill/cmpt225_09heaps.pdf(堆插入 - 幻灯片 16)由 John Edgar 博士撰写。

如果你们能阐明为什么上述方法之一更好,那就太好了?

【问题讨论】:

    标签: c++ tree heap binary-tree priority-queue


    【解决方案1】:

    将二进制堆实现为数组,通常有两种方法来实现插入:自顶向下或自底向上。链接 PDF 的幻灯片 17 描述了自下而上的做事方式。它在堆的末尾(最底部,最左侧的位置)添加新项目,并将其冒泡。这是幻灯片 16 中显示的策略 1 的实施。

    从性能的角度来看,这是更好的方法,因为平均而言,它需要更少的迭代来修复排序。请参阅 Argument for O(1) average-case complexity of heap insertion 了解详细说明。

    自上而下的方法,对应于幻灯片 16 上的策略 2,要求每次插入都进行 O(log n) 比较。此策略从根开始,并在堆中向下筛选项目。如果新项目小于(在最小堆中)它正在与之比较的节点,它将替换该节点处的项目,并且必须将刚刚替换的项目向下推。这一直持续到您到达堆的底部。不可能“提前退出”,因为您最终必须在叶级别的堆中放入一个新项目。

    我从来没有真正想过它是先确保顺序,然后确保完整性,但这本质上是自上而下的方法。

    第二种策略每次插入需要更多的迭代,并且在每次迭代期间也做更多的工作来保持顺序。

    【讨论】:

    • 好的,有道理。这一切都与程序执行排序所需的迭代次数有关。因此,最好检查完整性,然后修复排序。感谢您的澄清,现在对我来说很有意义:)
    • @Kourosh:在第一种情况下,您甚至不必“检查完整性”。将新项目放置在适当的位置可确保定义的完整性。
    • 是的,您是对的,我们不检查完整性。插入发生在数组的大小处,然后调用冒泡(即重新堆)算法将项目放置在正确的位置,从而固定顺序。另外,现在我记得为什么我的教授建议在插入后使用冒泡,在删除后使用冒泡(即减少工作量)。
    • 第16张幻灯片的措辞一开始很混乱,但从逻辑上考虑,方法1更好是合理的。
    猜你喜欢
    • 1970-01-01
    • 2016-05-07
    • 2019-07-12
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    相关资源
    最近更新 更多