は、次のPythonコードがpartition()
パーティションを2つにリストを分割機能に基づいています良いselection algorithm
です。 "pivotValue"より小さい値はリストの先頭に移動されます。 pivotValueより大きい値はリストの最後に移動されます。 これは、開始点から終了点までのリストをたどることでO(N)操作で実行され、ピボット値よりも小さい場合にのみ、リストの開始付近で値を移動するたびに移動します。
(実際には、大きな値を最小にしないため、大きな値をリストの先頭に移動することに注意してください)。
O(N)時間にリストを分割すると、リストの先頭にm個の大きな数字が残されます。もしm = 10であれば、それはあなたの10の大きな数字です。 mが10より大きい場合は、最大のm個の数字から10個の最大の数字を得るためにm個の最大の数字を再び分割する必要があります。 mが10より小さい場合、10 m以上の数字が必要なので、10 mの数字を見つけてm個の数字に追加して、必要な10個の数字を取得します。
したがって、私たちは最大の数字が10になるまでパーティショニングを続けます。これはselect()
メソッドによって行われます。全体の方法は通常非常に速いです。なぜなら、パーティションを作成するたびに、扱う数値の半分を残すからです。 (あなたが2で見なければならない数字の数を絶えず分けるなら、それは良いことです)。私たちが10以上の大きな数字を生成するパーティションを実行するたびに、小さすぎる数字のヒープ全体を無視するようになります。ここで
はコードです:
def partition(_list,left,right,pivotIndex):
pivotValue=_list[pivotIndex]
_list[right],_list[pivotIndex]=pivotValue,_list[right]
storeIndex=left
for i in range(left,right):
if _list[i] > pivotValue:
_list[storeIndex],_list[i]=_list[i],_list[storeIndex]
storeIndex+=1
_list[right],_list[storeIndex]=_list[storeIndex],_list[right]
return storeIndex
from random import randint
def select(_list,left,right,k):
if left==right:
return _list[:left+1]
pivotIndex=randint(left,right)
pivotNewIndex=partition(_list,left,right,pivotIndex)
pivotDist=pivotNewIndex-left+1
if pivotDist==k:
return _list[:pivotNewIndex+1]
elif k<pivotDist:
return select(_list,left,pivotNewIndex-1,k)
else:
return select(_list,pivotNewIndex+1,right,k-pivotDist)
_list=[1,2,109,2234,23,6,1,234,11,4,12451,1]
left=0
right=len(_list)-1
pivotIndex=4
print _list
"[1, 2, 109, 2234, 23, 6, 1, 234, 11, 4, 12451, 1]"
print partition(_list,left,right,pivotIndex) #partition is order(N).
"7" #index 7, so the lowest number are in the first 7 numbers of the list [1, 2, 1, 6, 1, 11, 4, 23]
print _list
"[1, 2, 1, 6, 1, 11, 4, 23, 2234, 109, 12451, 234]"
print select(_list,left,right,10)
"[1, 2, 1, 1, 4, 11, 6, 23, 109, 234]"
with open('nums.txt') as f:
numbers=map(int,f.readlines())
print select(numbers,0,len(numbers)-1,10)
"[1132513251, 2000, 23512, 13252365, 1235, 1251, 324, 100, 82, 82]"
この宿題ですか?または本からの運動? – ChrisW
それは宿題です。 –
これは明らかに[XY問題](http://www.perlmonks.org/?node_id=542341)です。問題はソートではなく、10の最大整数を見つけることです。最初にソートしてから上位10個のエントリを選択すると見つかる可能性がありますが、これは最善の解決策ではありません。最も良い解決策は、_pepsi_によって提供されるものです。 – pillmuncher