无限作为mergesort的哨兵?

时间:2011-04-06 14:35:20

标签: c

我正在阅读Cormen的“算法导论”,我发现了一种叫做哨兵的东西。

它在mergesort算法中用作工具来决定何时两个合并列表中的一个用尽。 Cormen在伪代码中使用无穷大符号作为哨兵,我想知道如何在C中实现这样的无限值。

5 个答案:

答案 0 :(得分:2)

哨兵只是一个虚拟值。对于字符串,您可能使用NULL指针,因为这不是列表中的明智之举。对于整数,您可以使用数据集中不太可能出现的值,例如:如果您正在处理列表年龄,那么您可以使用年龄-1来表示列表。

答案 1 :(得分:1)

你可以获得花车的“无限价值”,但这不是最好的主意。对于数组,请明确传递大小;对于列表,使用空指针sentinel。

答案 2 :(得分:1)

在C中,当您对数组进行排序时,通常会知道大小,因此您实际上可以对范围[begin, end)进行排序,其中end是一个超出数组末尾的范围。例如。 int a[n]可以排序为sort(a, a + n)

这允许你做两件事:

  • 使用尚未排序的数组部分递归调用您的排序(合并排序是一种递归算法)
  • 使用end作为哨兵。

答案 3 :(得分:1)

如果您知道列表中的元素范围从给定数据类型的最小值到最高值,则您正在查看的代码将不起作用。你必须提出其他的东西,我相信我可以做到。我现在面前有那本书,我正在查看导致你麻烦的代码,如果你知道从给定数据类型的最小值到最大值减去的值,我有一个对你有用的解决方案一个最多。打开该书直至第31页并查看合并功能。引起问题的线是第8和第9行,其中使用了无穷大的标记值。现在,我们知道两个数组每个都已经排序,我们只需要将它们合并以获得两倍大且排序顺序的数组。这意味着每一半中最大的元素位于子数组的末尾,并且两者中较大的元素是数组中最大的两倍大,我们将在合并函数完成后进行排序。我们需要做的就是确定这两个值中最大的值,将该值递增1,并将其用作我们的哨兵。因此,代码的第8行和第9行应替换为以下6行代码:

if L[n1] < R[n2]
  largest = R[n2]
else
  largest = L[n1]

L[n1 + 1] = largest + 1
R[n2 + 1] = largest + 1

这对你有用。我明天在我的算法课程中对这些东西进行了测试,我在这里发现了你的帖子并认为我会帮助你。作者在本书中对哨兵的使用总是让我感到烦恼,我绝对无法忍受他们对递归的热爱程度。迭代速度更快,在我看来通常更容易掌握和掌握。

答案 4 :(得分:0)

诀窍在于,只需在内部while循环中的一个列表中递增索引时,不必检查数组边界。因此,你需要比所有其他元素都大的哨兵。在c ++中,我通常使用std::numeric_limits<TYPE>::max()

C-equivalent应该是像INT_MAX, UINT_MAX, LONG_MAX等宏。这些都是很好的哨兵。如果您需要两个不同的标记,请使用..._MAX..._MAX - 1

这是假设您正在合并两个按升序排序的列表。