这是中位数算法的伪代码(稍作修改以适合您的示例)。维基百科中的伪代码未能描述selectIdx
函数调用的内部工作原理。
我已经在代码中添加了注释以进行解释。
// L is the array on which median of medians needs to be found.
// k is the expected median position. E.g. first select call might look like:
// select (array, N/2), where 'array' is an array of numbers of length N
select(L,k)
{
if (L has 5 or fewer elements) {
sort L
return the element in the kth position
}
partition L into subsets S[i] of five elements each
(there will be n/5 subsets total).
for (i = 1 to n/5) do
x[i] = select(S[i],3)
M = select({x[i]}, n/10)
// The code to follow ensures that even if M turns out to be the
// smallest/largest value in the array, we'll get the kth smallest
// element in the array
// Partition array into three groups based on their value as
// compared to median M
partition L into L1<M, L2=M, L3>M
// Compare the expected median position k with length of first array L1
// Run recursive select over the array L1 if k is less than length
// of array L1
if (k <= length(L1))
return select(L1,k)
// Check if k falls in L3 array. Recurse accordingly
else if (k > length(L1)+length(L2))
return select(L3,k-length(L1)-length(L2))
// Simply return M since k falls in L2
else return M
}
以你为例:
中位数函数的中位数将在 45 个元素的整个数组中调用,例如 (with k = 45/2 = 22
):
median = select({48 49 50 51 52 43 44 45 46 47 38 39 40 41 42 33 34 35 36 37 28 29 30 31 32 23 24 25 26 27 18 19 20 21 22 13 14 15 16 17 8 9 10 53 54}, 45/2)
第一次M = select({x[i]}, n/10)
调用时,数组{x[i]}
将包含以下数字:50 45 40 35 30 20 15 10
。在此调用中,n = 45
,因此选择函数调用将是M = select({50 45 40 35 30 20 15 10}, 4)
第二次M = select({x[i]}, n/10)
调用时,数组{x[i]}
将包含以下数字:40 20
。在此通话中,n = 9
因此通话将是M = select({40 20}, 0)
. 这个 select 调用将返回并赋值M = 20
。
现在,到了你有疑问的地方,我们L
现在M = 20
用k = 4
.
记住L
这里的数组是:50 45 40 35 30 20 15 10
.
数组将根据规则划分为,L1, L2
和。因此:
因为,它大于。因此,现在将通过以下递归调用继续搜索:
转换为:
L3
L1 < M
L2 = M
L3 > M
L1: 10 15
L2: 20
L3: 30 35 40 45 50
k = 4
length(L1) + length(L2) = 3
return select(L3,k-length(L1)-length(L2))
return select({30 35 40 45 50}, 1)
结果将返回 30。(因为 L 有 5 个或更少的元素,因此它将返回第 k 个元素,即排序数组中的第一个位置,即 30)。
现在,M = 30
将在第一次select
函数调用中接收到 45 个元素的整个数组,并且将数组L
周围分开的相同分区逻辑M = 30
将应用于最终获得中位数的中位数。
呸!我希望我足够详细和清楚地解释中位数算法的中位数。