import random
import os,sys
'''隨機生成不大於max的長度位n的列表
'''def genlist(n,max):
result =
for i in range(n):
print(result)
return result
'''從給定的列表中獲取k個有序列表分組
'''def splitsortedlist(sourcelist,k):
splits =
rim = len(sourcelist)%k
step = len(sourcelist)//k
for i in range(k):
li = sourcelist[i*step:i*step+step]
if rim >0 and i==k-1:
li = li + sourcelist[step * k: step*k + rim]
li.sort(reverse=true)
if li != :
print(splits)
return splits
'''定義調整函式
s是buf陣列的下標
'''def adjust(s):
t = (s+k)//2 #取s位的父節點
#如果當前節點不是根節點則進入下次迴圈,否則跳出
while t>0:
#比較當前節點值與父節點對應的值,如果父節點勝出則記錄失敗者並將當前節點換成勝利者
if buf[s] > buf[ls[t]]:
l = ls[t]
ls[t] = s
s = l
t = t//2
#記錄最終勝利者到ls[0]
ls[0] = s
'''定義敗者樹構建函式
'''def build():
#新增最小值-1到buf尾部
#將敗者樹中間節點全部初始化為最小值所在位置即len(buf)-1
for i in range(len(buf)):
#依次調整buf列表中所有位置
for i in range(k):
adjust(i)
maxint = sys.maxsize
minint = -1
k = 5 #5路歸併
#生成測試用例列表長度位33,每個元素是不大於100的隨機正整數
source = genlist(33,100)
#將待排序數列分成k組
source_split = splitsortedlist(source,k)
ls =
buf =
#用每組的第乙個元素初始化buf列表
for i in range(len(source_split)):
#構建初始化buf的敗者樹
build()
sorted_list =
#迴圈取出最後勝利者,讀取新元素進入buf並調整敗者樹
while buf[ls[0]] < maxint:
winner = ls[0]
buf[winner] = source_split[winner].pop()
adjust(winner)
source.sort()
print(source)
assert(source == sorted_list)
print(sorted_list)
k路合併 敗者樹演算法
假定有k個有序陣列,每個陣列中含有n個元素,您的任務是將它們合併為單獨的乙個有序陣列,該陣列共有kn個元素。設計和實現 乙個有效的分治演算法解決k 路合併操作問題,並分析時間複雜度。介於本人水平有限,在參考了許多大神的部落格後貼上自己的 public class multiplemerge arr ...
用敗者樹優化K路歸併排序
圖9.16給出的歸併過程屬於2路平衡歸併。做k路平衡歸併 k way balanced merging 時,如果有m個初始歸併段,則相應的歸併樹有 logkm 1層,南非要歸併 logkm 趟。做內部歸併時,在k個物件中選擇最小者,需要順序比較k 1次。每趟歸併u個物件需要做 u 1 k 1 次比較...
外排序的C 實現(歸併時利用敗者樹)
參考部落格 1 問題描述 輸入 乙個最多含有n個不重複的正整數 也就是說可能含有少於n個不重複正整數 的檔案,其中每個數都 小於等於 n,且n 10 7。輸出 得到按從小到大公升序排列的包含所有輸入的整數的列表。條件 最多有大約1mb的記憶體空間可用,但磁碟空間足夠。且要求執行時間在5分鐘以下,10...