假设我有一个大小为 n 的未排序数组 A。
如何在线性时间内从原始未排序列表中找到第 n/2、n/2−1、n/2+1 个最小元素?
我尝试在维基百科中使用选择算法(我正在实现基于分区的通用选择算法)。
function partition(list, left, right, pivotIndex)
pivotValue := list[pivotIndex]
swap list[pivotIndex] and list[right] // Move pivot to end
storeIndex := left
for i from left to right-1
if list[i] < pivotValue
swap list[storeIndex] and list[i]
increment storeIndex
swap list[right] and list[storeIndex] // Move pivot to its final place
return storeIndex
function select(list, left, right, k)
if left = right // If the list contains only one element
return list[left] // Return that element
select pivotIndex between left and right //What value of pivotIndex shud i select??????????
pivotNewIndex := partition(list, left, right, pivotIndex)
pivotDist := pivotNewIndex - left + 1
// The pivot is in its final sorted position,
// so pivotDist reflects its 1-based position if list were sorted
if pivotDist = k
return list[pivotNewIndex]
else if k < pivotDist
return select(list, left, pivotNewIndex - 1, k)
else
return select(list, pivotNewIndex + 1, right, k - pivotDist)
但我还没有理解 3 或 4 个步骤。我有以下疑问:
- 我是否选择了正确的算法,它是否真的能在我的程序的线性时间内工作。我有点困惑,因为它类似于快速排序。
- 调用函数时从主函数中选择,左、右和k的值是多少。考虑我的数组是列表 [1...N]。
- 我是否必须调用 select 函数 3 次,一次查找 n/2th 最小,另一次查找 n/2+1 th 最小,再调用一次 n/2-1th 最小,还是可以一次完成打电话,如果是,怎么打?
- 同样在函数选择(第三步)“在左右之间选择pivotIndex”中,我应该为我的程序/目的选择什么pivotIndex 值。
谢谢!