邋He堆排序

时间:2014-10-20 14:41:23

标签: algorithm heap

有没有人听说过这种堆修复技术:SloppyHeapSort?它使用“Sloppy”筛选方法。基本上,它需要修复元素,将其移动到堆的底部(不将其与子项进行比较),方法是将其替换为较大的子项,直到它碰到底部。然后,调用筛选直到它到达正确的位置。这样就可以进行超过lg n次的比较(在大小为n的堆中)。

但是,这不能用于堆构造,仅用于堆修复。为什么是这样?我不明白为什么如果你试图建立一个堆它不会起作用。

2 个答案:

答案 0 :(得分:3)

如果部署得当,该算法肯定可以用作堆构造算法的一部分。在堆构造期间,修复的子堆的根不是数组的开头,这会影响sift-up的实现(当达到数组的当前元素时需要停止,这有点复杂)而不是继续到堆的底部。)

应该注意的是,该算法具有与标准堆修复算法相同的渐近性能;但是,可能涉及较少的比较。在某种程度上,这是因为在堆交换堆的根(最大元素)之后调用标准堆修复算法。

最后一个元素不一定是堆中的最小元素,但它肯定可能接近底部。在交换之后,标准算法将交换的元素向下移动到log 2 N次,每个步骤需要两次比较;因为该元素可能属于堆的底部附近,大多数时候将执行最大比较次数。但偶尔也只能进行两到四次比较。

"马虎"算法反而从移动"孔开始#34;从堆的顶部到靠近底部的某个地方(log 2 N比较),然后向上移动最后一个元素,直到找到它为止,这通常只需要进行一些比较(但可以,最糟糕的情况是,接近log 2 N比较。)

现在,在heapify的情况下,堆修复不是使用子堆中的最后一个元素执行的,而是使用从原始向量中获取的先前未看到的元素。这实际上并没有太多地改变平均性能分析,因为如果你使用随机元素开始堆修复,而不是可能很小的元素,预期的筛选操作数仍然接近最大值。 (堆的一半在最后一级,因此需要随机元素的最大筛选数的概率是一半。)

虽然草率算法(可能)改进了元素比较的数量,但它增加了元素移动的数量。经典算法最多执行log 2 N个交换,而草率算法至少执行log 2 N个交换,以及在筛选期间执行额外的交换。 (在这两种情况下,交换都可以通过不插入新元素直到其实际位置已知,将内存存储的数量减半来改进移动。)

作为附言,我无法找到任何关于你的"马虎"算法。总的来说,在询问提议的算法时,通常最好包含一个链接

答案 1 :(得分:1)

有一个线性时间算法来构造堆。我相信作者的意思是使用这种方法来构建堆是没有效率的,并且存在更好的算法。当然,您可以通过使用所描述的策略逐个添加元素来构建堆 - 您可以做得更好。