* ベストもアベレージも O (n log (n))
ただし、平均速度はクイックソートの方が上。
def comp(a, b):
if a > b:
return 1
elif a < b:
return -1
else:
return 0
# 親と子を比較し、子の方が大きければ交換
# 交換があれば更なる交換がないか再帰的に調べる
def heapify(arr, comp_func, idx, max_idx):
left = 2 * idx + 1
right = 2 * idx + 2
largest = 0
if left < max_idx and comp_func(arr[left], arr[idx]) > 0:
largest = left
else:
largest = idx
if right < max_idx and comp_func(arr[right], arr[largest]) > 0:
largest = right
if largest != idx:
tmp = arr[idx]
arr[idx] = arr[largest]
arr[largest] = tmp
heapify(arr, comp_func, largest, max_idx)
# 子は必ず親より小さい、という性質を持つ 2 分木を作成する
# 大きい数字が勝ち上がっていく、トーナメントのようなイメージ
def buildHeap(arr, comp_func, n):
for i in range(n / 2 - 1, -1, -1):
heapify(arr, comp_func, i, n)
def heapSort(arr, n, comp_func):
# 初回のみ下から木を作る
buildHeap(arr, comp_func, n)
for i in range(n - 1, 0, -1):
# 最大値が配列先頭にあるので、終端と交換
tmp = arr[0]
arr[0] = arr[i]
arr[i] = tmp
# 一度木が作成済みなので先頭から交換の有無を調べる
# 上位に交換がなければ、下位に影響はない
heapify (arr, comp_func, 0, i)
a = range(0, 500)
random.shuffle(a)
print a
heapSort(a, len(a), comp)
print a
0 件のコメント:
コメントを投稿