给定k个排好序的序列s1,s2,…,sk,用2路合并算法将这k个序列合并成一个序列。假设所采用的2路合并算法合并两个长度分别为m和n的序列需要m+n-1次比较。试设计一个算法确定合并这个序列的最优合并顺序,使所需要的总比较次数最少。
测试用例: 4(序列数)
5 12 11 2(序列中的元素数)
输出: 78(最差情况) 52(最优情况)
分析:
最差情况就是比较次数最多的情况,因为合并之后的序列还会继续与剩下的序列合并,所以应先从中挑选序列长度最长的两个序列进行合并,然后再在剩下的序列中(包括刚才合并后的序列)挑选序列长度最长的两个序列进行合并,直至序列被全部合并,这样就可使下一次合并的次数最多。
最优情况与最差情况同理。
def Most(num):
num1=num.copy()
#将列表num1降序排列
num1.sort(reverse=True)
print(num1)
Times=0#总的比较次数
times=0#每两个序列的比较次数
for i in range(n-2):
#取序列长度最长的两个序列先进行比较
times=num1[0]+num1[1]
Times=Times+times-1
#删除已比较的序列
del num1[0]
del num1[0]
#加入合并后的序列
num1.append(times)
num1.sort(reverse=True)
times=num1[0]+num1[1]-1
Times=Times+times
return Times
def Least(num):
num2=num.copy()
#将列表num2升序排列
num2.sort()
print(num2)
Times=0#总的比较次数
times=0#每两个序列的比较次数
for i in range(n-2):
#取序列长度最短的两个序列先进行比较
times=num2[0]+num2[1]
Times=Times+times-1
#删除已比较的序列
del num2[0]
del num2[0]
#加入合并后的序列
num2.append(times)
num2.sort()
times=num2[0]+num2[1]-1
Times=Times+times
return Times
#从文件中读出数据
file_readpath = 'input.txt'
with open(file_readpath) as file:
txt = file.read()
txt=txt.split('\n')
#n代表数据的个数
n=eval(txt[0])
num=[]
txt=txt[1].split()
for i in range(n):
num.append(eval(txt[i]))
#输出结果用于验证
most=Most(num)
#print(duo)
least=Least(num)
#print(Shao)
print("最多次数为:",most)
print("最少次数为:",least)
#将结果存入文件output.txt
file_writepath = 'output.txt'
file=open(file_writepath,"w")
file.write(str(most)+' '+str(least))
file.close()
运行结果为
最多次数为: 78
最少次数为: 52