我在http://students.ceid.upatras.gr/~lebenteas/Heapsort-using-Multiple-Heaps-final.pdf找到了使用多个堆的Heapsort
变体。该解决方案提出,而不是传统的Heapsort
算法,在每次交换之后,我们再做一个siftdown
以将当前堆中的最高值带到根,我们可以做其他一些事情。然而,他们究竟是什么意思“其他事情”,我无法理解。
例如,有一次他们说我们“忘记”,暂时存在根。这肯定意味着我们目前正在停止与最后一个元素交换最高元素堆的元素。然而,就在某些行之后,他们说到目前为止,已经在堆的已排序部分传输了两个元素。,这与交换尚未完成的命题背道而驰。同样在第97页的图中,缺少值为1的节点,我不知道如何。
有人能让我知道作者究竟要传达的是什么,以及它有多值得吗?
答案 0 :(得分:1)
(你问的那一行是在第2.3节,所以我将解释第2.3节中提出的heapsort的变化:)
当作者说我们“忘记”根的存在时,不意味着他们停止交换最高元素。交换已完成,但它们会暂时延迟重建堆。在将最高元素交换到根位置后,它们比较2个子堆的根,并将其中一个或另一个与下一个最高元素交换。 然后,在执行 2 交换(而不是1)后,他们重建堆。
然后他们在第3节和第4节中进一步采用了这个想法,并提出了 heapsort的另一个变体,它使用了多个堆。
如何在阵列中保留多个堆? (为了使它具体化,让我们谈谈2堆。)那么,你如何保持一堆?根在索引0处,其子节点为1和2,然后左子节点的子节点为3和4等,对吧?
将2个堆放在一个数组中,将2个根保持为0和1.第一个根的子节点位于2和3,然后第2个根节点的子节点位于4和5 ...这样的通过对索引进行简单的算术运算,仍然可以在树上上下导航。
标准堆重复2个步骤:将根与“堆”区域中的最后一个元素交换,然后siftDown
重建堆。 此 heapsort重复以下3个步骤:比较2个根以查看哪个更大,将那个与“堆”区域中的最后一个元素交换,然后在适当的位置调用siftDown
堆。
这需要在每个步骤进行额外的比较,但siftDown
操作适用于稍浅的堆,这可以节省多个比较。