3
假设我有一个大小为n的未排序数组A.选择算法来查找中位数,左侧和右侧的元素
如何在线性时间内从原始未排序列表中找到n/2,n/2-1,n/2 + 1个最小元素?
我试图使用wikipedia中的选择算法(基于分区的通用选择算法就是我正在实现的)。
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个步骤。我有以下的疑问:
- 我选择了正确的算法,它会真正在线性时间为我的程序工作。我有点困惑,因为它类似于快速排序。
- 在调用函数时从主函数中选择,left,right和k的值是多少。考虑我的数组是列表[1 ... N]。
- 我是否需要三次调用select函数,一次是找到n/2次最小,另一次是找到n/2 + 1次最小,还有一次是第n/2次最小,还是可以做到如果是,如何?
- 同样在函数中选择(第三步)“选择左右之间的pivotIndex”,我应该为我的程序/目的选择什么值的pivotIndex。
谢谢!