# 树形选择排序(锦标赛排序)
# 原理
将无序集合进行两两分组排序,将找出的每组的最小值再进行两两排序,
以此模式直到找出最小的值,将这个值纪录下来并从第一次两两分组的排序集合中移除这个值,
然后进行第二轮,直到排序结束。
原始集合:{5,2,4,6,8,1,9,7,10,3}
第一次两两分组:{5,2} {4,6} {8,1} {9,7} {10,3}
第一轮:{5,2} {4,6} {8,1} {9,7} {10,3} => {2,4,1,7,3} => {2,4} {1,7} {3} => {2,1,3} => {2,1} {3} => {1,3} => {1}
第二轮:{5,2} {4,6} {8} {9,7} {10,3} => {2,4,8,7,3} => {2,4} {8,7} {3} => {2,7,3} => {2,7} {3} => {2,3} =>{2}
第三轮:{5} {4,6} {8} {9,7} {10,3} => {5,4,8,7,3} => {5,4} {8,7} {3} =>{4,7,3} => {4,7} {3} =>{4,3}=>{3}
1
2
3
4
5
2
3
4
5
# 实现
inputArr = [199383, 10, 34, -1,-32,-29, 4, 0, 34, 5, 4, 36, 1, 8, 123, 453, 1008]
length=len(inputArr)
print("未排序集合:{0}".format(inputArr))
sortArr=[None]*len(inputArr)
for sortIndex in range(0,length):
queryMinArr=[list(range(0,length))]
while(len(queryMinArr)>0):
itemArr=queryMinArr.pop()
itemLength=len(itemArr)
# 当itemLenth==1时表示一次排序结束,记录并在源数组中将值这是为None
if(itemLength==1):
sortArr[sortIndex]=inputArr[itemArr[0]]
inputArr[itemArr[0]]=None
break
# 两两分组
groupArr=[]
itemGroupLength=itemLength//2 if(itemLength%2==0) else itemLength//2+1
for index in range(0,itemGroupLength):
tmpArr=[]
# 分组时移除值为None
for tmpIndex in range(index*2,index*2+2):
if(tmpIndex>=itemLength):
continue
if(inputArr[itemArr[tmpIndex]]!=None):
tmpArr.append(itemArr[tmpIndex])
if(len(tmpArr)>0):
groupArr.append(tmpArr)
minItemArr=[]
for item in groupArr :
if(len(item)==1):
minItemArr.append(item[0])
continue
minIndex =(item[0] if(inputArr[item[0]]<inputArr[item[1]]) else item[1])
minItemArr.append(minIndex)
queryMinArr.append(minItemArr)
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
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