使用归并排序计算逆序对
我写了一个合并排序的程序,用Python做的,运行得很好。但是我对它进行了修改,想要计算排序过程中有多少个逆序对,现在却出现了错误:
这是我的代码:
def merge_list(left,right,c):
result=[]
i,j=0,0
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
print "Left result",result
i=i+1
elif left[i] > right[j]:
result.append(right[j])
print "Right result",result
j=j+1
if right[j] < left[i] and i<j:
c=c+1
result=result+left[i:]
result=result+right[j:]
print "Inversions: ",c
return result,c
def sort_and_count(lis,count):
if len(lis)<2:
return lis
middle=len(lis) / 2
left,c1=sort_and_count(lis[:middle],count)
print "left",left
right,c2=sort_and_count(lis[middle:],count)
print "right",right
m,c=merge_list(left,right,count)
c=c+c1+c2
return m,c
if __name__=="__main__":
print "Enter 6 elements: "
i=0;lis=[];merge_lis=[];inv=0
while i<=5:
x=int(raw_input())
lis.append(x)
i=i+1
count=0
merge_lis,inv=sort_and_count(lis,count)
print "Sorted list is: ",merge_lis,inv
这是我的错误信息:
Traceback (most recent call last):
File "Sort_and_count.py", line 53, in <module>
merge_lis,inv=sort_and_count(lis,count)
File "Sort_and_count.py", line 31, in sort_and_count
left,c1=sort_and_count(lis[:middle],count)
File "Sort_and_count.py", line 31, in sort_and_count
left,c1=sort_and_count(lis[:middle],count)
ValueError: need more than 1 value to unpack
我在这个方法上哪里出错了呢?
5 个回答
1
这个错误信息告诉你,sort_and_count
这个函数只返回了一个值。这个函数里只有两个返回值,所以问题出在这个地方:
if len(lis)<2:
return lis
3
其实,你实现的算法用来计算逆序对的方式是错误的。
1) 在函数 merge_list
中,不应该使用以下这段代码:
elif left[i] > right[j]:
result.append(right[j])
print "Right result",result
j=j+1
if right[j] < left[i] and i<j:
c=c+1
你应该使用这段代码:
elif right[j] < left[i]:
result.append(right[j])
j += 1
inv_count += (len(left)-i)
2) 函数 merge_list
不需要输入变量 c
。
3) 函数 sort_and_count
也不需要输入变量 count
。
试试这段代码:
def merge_list(left,right):
result = list()
i,j = 0,0
inv_count = 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
inv_count += (len(left)-i)
result += left[i:]
result += right[j:]
return result,inv_count
def sort_and_count(array):
if len(array) <= 1:
return array, 0
middle = len(array) // 2
left,inv_left = sort_and_count(array[:middle])
right,inv_right = sort_and_count(array[middle:])
merged, count = merge_list(left,right)
count += (inv_left + inv_right)
return merged, count
if __name__=="__main__":
array = [2,3,1,4,5]
merge_array,inversions = sort_and_count(array)
print 'Start with array: %s;\nSorted array: %s;\nInversions: %s.'%(array,merge_array,inversions)
1
这一行:
return lis
这是个问题,因为你期望 sort_and_count
返回一个包含两个值的元组,所以当它只返回一个值时,你在像 left,c1=sort_and_count(lis[:middle],count)
这样的行中就会遇到元组解包的问题。这一行应该返回两个值,就像那个方法的最后一行:
return m,c