我正在学习合并排序,并且在合并步骤中使用了哨兵作为无限。
以下是Cormen书中的算法。 为什么我们在步骤8和9中使用了无穷大
MERGE(A, p, q, r)
1 n1 ← q − p + 1
2 n2 ← r − q
3 create arrays L[1 . . n1 + 1] and R[1 . . n2 + 1]
4 for i ← 1 to n1
5 do L[i ] ← A[ p + i − 1]
6 for j ← 1 to n2
7 do R[ j ] ← A[q + j ]
8 L[n1 + 1] ← ∞
9 R[n2 + 1] ← ∞
10 i ← 1
11 j ← 1
12 for k ← p to r
13 do if L[i ] ≤ R[ j ]
14 then A[k] ← L[i ]
15 i ← i + 1
16 else A[k] ← R[ j ]
17 j ← j + 1
答案 0 :(得分:8)
标记值是一个虚拟值,用于区分应该存在的值(例如用户输入)和控制值(需要特殊处理的值)。一个简单的例子是使用null to null来标记列表的结尾。
在这种特定情况下,当列表的两半被合并回来时,使用无穷大简化了比较逻辑(例如,当合并任何与无穷大相比的东西将会更少时,所以处理结束时合并简化了。)
答案 1 :(得分:4)
sentinel值只是一个没有有效值的值。
如果我的域名限制为正非零数字,则零可以是哨兵。
如果我的域名限制为正数,否则我将使用无符号整数,我可以使用有符号整数和负数作为哨兵。 (当然,我失去了无符号范围的上半部分。)
如果我使用指针指向一个值,则空指针可以是一个标记。
如果我使用的是一个c-string,它是一个指针(或一个衰减到指针的数组),我可以使用空指针,或者在某些情况下指向(char) 0
(“空字符串“),作为哨兵。
哨兵只是您有效输入永远无法承受的值。由于它不能被误认为是有效值,因此当您的代码看到标记值时,它可以执行“特殊的操作”,这不是对有效值执行的正常处理。
答案 2 :(得分:2)
在这种情况下,在每个递归步骤中将无穷大(大于任意数字)添加到每个子数组的末尾,将在以下情况下避免在合并两个子数组时的额外比较
在两种情况下都不需要编写额外的逻辑,以检查是否有任何数组结束,如果结束写一些额外的代码。