サイズnのソートされていない配列Aがあるとします。
線形時間で元のソートされていないリストからn/2、n / 2-1-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回呼び出す必要がありますか?1回はn / 2番目に小さいものを見つけるため、もう1回はn / 2 + 1番目に小さいものを見つけるため、もう1回はn /2-1番目に小さいものを見つけるためです。はいの場合、どのように電話しますか?
- また、関数select(3番目のステップ)「selectpivotIndex between left and right」で、プログラム/目的のためにピボットインデックスのどの値を選択する必要がありますか。
ありがとう!