我正在学习“算法简介”教科书第二版。在第9章(中位数和阶数统计)中,我无法理解为什么在Randomize_Select算法中需要这个额外的k。考虑一下本书中算法的伪代码。
RANDOMIZED-SELECT(A, p, r, i)
1 if p = r
2 then return A[p]
3 q ← RANDOMIZED-PARTITION(A, p, r)
4 k ← q - p + 1
5 if i = k ▹ the pivot value is the answer
6 then return A[q]
7 elseif i < k
8 then return RANDOMIZED-SELECT(A, p, q - 1, i)
9 else return RANDOMIZED-SELECT(A, q + 1, r, i - k)
我的问题是为什么我们需要k?我以这种方式实现了该算法,并且该算法起作用了(对于测试该算法的所有示例)。
RANDOMIZED-SELECT(A, p, r, i)
1 if p = r
2 then return A[p]
3 q ← RANDOMIZED-PARTITION(A, p, r)
4 if i = q ▹ the pivot value is the answer
5 then return A[q]
6 elseif i < q
7 then return RANDOMIZED-SELECT(A, p, q - 1, i)
8 else return RANDOMIZED-SELECT(A, q + 1, r, i)
由于从分区过程返回的q是一个索引,该索引包含排序后应该包含的集合中的元素,因此如果该索引是我们要搜索的内容,则只返回它,否则,我们对该部分进行相同的递归包含元素。为什么需要k? 为什么算法要关心每个子集中元素的顺序?为什么我们不关心索引呢?我的更改对所有情况都有效吗?
答案 0 :(得分:0)
它返回到i
中RANDOMIZED-SELECT
的定义。 i
在传递的数组的范围内,该函数从数组p
的{{1}}到r
开始。因此,应从数组A
的指定的第一位开始计算所选值q
。因此,我们应该计算与起始索引A
相关的k
(传递的数组中的位置)。
此外,由于此处的索引基于p
,因此1
应该为k
。
例如,假设q - p + 1
是一个大小为10的数组,而A
是p = 5,
。因此,r = 8
从i
更改为1
。因此,我们应该将介于3
和q
之间的5
映射为应从8
缩放到1
;因此,3
与k
的标度与i
的标度相同!