私は2つのheapsort
アルゴリズムを持っています。最初のものは私が書いたもので、2 番目のものはどこかのウェブサイトから取ったものです。私によると、どちらも同じロジックを持っていますが、2 番目の方が 1 番目よりもパフォーマンスが優れています。これが起こっている理由は何ですか?私が見ることができる唯一の違いは、私のものは再帰を使用しているのに対し、他のものは繰り返し実行していることです。それだけで差別化要因になるの?
私のコード:
def heapify(arr,i,n):
pivot = arr[i] #the value of the root node
left,right = (i<<1)+1,(i<<1)+2 #indices of the left and right subtree root nodes
if right <= n-1: #if right is within the array, so is left
if arr[left] <= pivot and arr[right] <= pivot:
return #if both are less than the root node, it's already heapified
maximum = left if arr[left] >= arr[right] else right #else find which child has a higher value
arr[maximum],arr[i] = arr[i],arr[maximum] #swap the root node with that child
return heapify(arr,maximum,n) #make the changed child the new root and recurse
else:
if left <= n-1: #right is outside the array, so check for left only
if arr[left] <= pivot:
return
arr[i],arr[left] = arr[left], arr[i] #same logic as above
return heapify(arr,left,n)
else:
return
def heapit(array,n):
for i in range((len(array)-1)/2,-1,-1): #all elements after (len(array)-1)/2 are the leaf nodes, so we have to heapify earlier nodes
heapify(array,i,n)
def heapsort(array):
n = len(array)
for i in range(n,0,-1):
heapit(array,i) #make the array a heap
array[0],array[i-1] = array[i-1],array[0] #swap the root node with the last element
他のコード:
def HeapSort(A):
def heapify(A):
start = (len(A) - 2) / 2
while start >= 0:
siftDown(A, start, len(A) - 1)
start -= 1
def siftDown(A, start, end):
root = start
while root * 2 + 1 <= end:
child = root * 2 + 1
if child + 1 <= end and A[child] < A[child + 1]:
child += 1
if child <= end and A[root] < A[child]:
A[root], A[child] = A[child], A[root]
root = child
else:
return
heapify(A)
end = len(A) - 1
while end > 0:
A[end], A[0] = A[0], A[end]
siftDown(A, 0, end - 1)
end -= 1
サイズが約 100,000 の小さな配列であっても、その差はかなり大きくなります。関数に並べ替える配列を渡すだけで、どちらかのコードを呼び出しています:HeapSort(list)
またはheapsort(list)
.
編集:
heapsort
関数を次の関数に置き換えました。
def heapsort(array):
n = len(array)
heapit(array,n)
array[n-1],array[0] = array[0],array[n-1]
for i in range(n-1):
heapify(array,0,n-1-i)
array[n-i-2],array[0] = array[0],array[n-i-2]
これにより同等のパフォーマンスが得られますが、それでも遅くなります。100 万ドルの配列の場合、結果はほぼ 20 秒 : 4 秒です。他に何ができますか?