# 多路平衡归并排序(胜者树、败者树)
多路归并排序用作大数据集合的排序,通常因为内存资源不足,只能分段排序。
多路归并通常结合二叉树进行排序即败者树与胜者树。
胜者树: 每次筛选最小值作为根结点
败者树: 每次筛选最大值作为根节点
平衡指将大集合平分为多个相同元素个数的集合,唯一与置换置换选择排序
的不同之处
# 原理
1. 将无序数组分割成多个无序数组,分割成N个就是N路排序
2. 取每个无序数组的第一个元素两两排序,选取最小值或最大值,同附近的两两排序结果再次比较,直到选出最小值
3. 将最小值放在有序集合中,并将原最小值的位置替换为该无序数组段的下一个元素
4. 重复2-3步骤,直到全部排序完成
# 实现
inputArr = [199383, 10, 34, -1, -32, -29, 4,
0, 34, 5, 4, 36, 1, 8, 123, 453, 1008]
print("未排序集合:{0}".format(inputArr))
'''
将无序数组进行5路排序
N: 1 2 3 4 5
0: 199383 -32 34 1 1008
1: 10 -29 5 8
2: 34 4 4 123
3: -1 0 36 453
'''
length=len(inputArr)
sortArr=[None]*length
groupArr=[]
# 根据无序数组大小分割成一次内存能容下的元素个数
count=4
groupCount=length//count if(length%count==0) else length//count+1
for nIndex in range(0,groupCount):
nStratIndex=nIndex*4
nEndIndex=(nIndex+1)*4-1
nEndIndex=nEndIndex if(nEndIndex<=length) else length-1
groupArr.append([nIndex*4,nEndIndex])
# 将每一路无序数组先排序
for index in range(nStratIndex+1, nEndIndex+1):
while(index !=0):
if(inputArr[index] > inputArr[index-1]):
break
inputArr[index], inputArr[index-1]\
= inputArr[index-1], inputArr[index]
index -= 1
sortIndex=0
while sortIndex<length:
minGroupIndex=0
for groupIndex in range(1,groupCount):
minItem=inputArr[groupArr[minGroupIndex][0]]
item = inputArr[groupArr[groupIndex][0]]
minGroupIndex=minGroupIndex if(minItem<item) else groupIndex
sortArr[sortIndex]=inputArr[groupArr[minGroupIndex][0]]
groupArr[minGroupIndex][0]+=1
if(groupArr[minGroupIndex][0]>groupArr[minGroupIndex][1]):
groupArr.remove(groupArr[minGroupIndex])
groupCount-=1
sortIndex+=1
print("已排序集合:{0}".format(sortArr))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44