如何摆脱合并排序中的哨兵?

时间:2013-09-14 19:12:36

标签: algorithm mergesort divide-and-conquer

据我所知,使用sentinel有点等同于零填充(从复杂性的角度来说)。

对于那些不知道零填充的人:

我们附加了一些零(或其他一些值,无关紧要),使大小为2的幂,在我们应用合并排序算法后,我们消除了那些附加的零。

但是,除了零填充之外,还有其他方法可以摆脱哨兵吗?

1 个答案:

答案 0 :(得分:3)

你混淆了两个不相关的概念。它们并不接近等价物。 sentinel是放置在列表(逻辑)末端的额外元素。

它故意有一些“限制”值,允许通常会停止遍历数组的测试停止数组端的遍历。

例如,如果我们在列表[1,8,4,7]中查找值大于5的第一个元素,没有标记,则算法将是:

i = 0; 
while i < 4 { if a[i] > 5 return i; i = i + 1 }
return "not found"

我们将继续添加一个大于5的元素,比如6. [1,8,4,7,6]。现在搜索变为

i = 0;
while a[i] <= 5 { i = i + 1 }
return if i < 4 then i else "not found"

注意第二个代码每次迭代都有一个比较。第一个有两个。这就是哨兵的原因。它们允许更少的比较。

所以你不想“摆脱”哨兵。它们是使循环运行得更快的工具。它们仅适用于某些情况。当你遇到其中一种情况时,它们是一个有用的选择。

另一方面,零填充通常用于使递归的分而治之算法更简单。快速傅立叶变换就是一个例子。对于长度为2 ^ n的输入,它具有非常简单的实现。虽然存在其他大小数据的算法,但它们要复杂得多。因此,将数据零填充到下一个2的幂大小是很常见的。

所以你也不想摆脱零填充。这只是一个实现选项。

无论是哨兵还是航空填充都不适用于mergesort。