基于我从CLRS书中学到的东西,我已经在python中完成了我的合并排序算法的一个变体,并将它与麻省理工学院介绍性计算机科学书上的实现进行了比较。我在我的算法中找不到问题,IDLE给我一个超出范围的索引,尽管对我来说一切都很正常。我不确定这是否是由于麻省理工学院算法中的借鉴想法造成的混乱(见下文)。在python中执行mergesort算法变化的索引超出范围?
lista = [1,2,3,1,1,1,1,6,7,12,2,7,7,67,4,7,9,6,6,3,1,14,4]
def merge(A, p, q, r):
q = (p+r)/2
L = A[p:q+1]
R = A[q+1:r]
i = 0
j = 0
for k in range(len(A)):
#if the list R runs of of space and L[i] has nothing to compare
if i+1 > len(R):
A[k] = L[i]
i += 1
elif j+1 > len(L):
A[k] = R[j]
j += 1
elif L[i] <= R[j]:
A[k] = L[i]
i += 1
elif R[j] <= L[i]:
A[k] = R[j]
j += 1
#when both the sub arrays have run out and all the ifs and elifs done,
# the for loop has effectively ended
return A
def mergesort(A, p, r):
"""A is the list, p is the first index and r is the last index for which
the portion of the list is to be sorted."""
q = (p+r)/2
if p<r:
mergesort(A, p, q)
mergesort(A, q+1, r)
merge (A, p, q, r)
return A
print mergesort(lista, 0, len(lista)-1)
我已经尽可能靠近我可以跟着CLRS的伪代码,只是不使用“无限值”的L和R的结束,这将继续比较(这是效率不高?)。我试图在麻省理工学院的书中加入这样的想法,即简单地将剩余的L或R列表复制到A,以便变异A并返回一个排序列表。但是,我似乎无法找到它出了什么问题。另外,我不明白为什么伪代码需要'q'作为输入,因为q对于中间索引计算为(p + q)/ 2。另一方面,从MIT的书中,我们看到了一些看起来非常优雅的东西。
def merge(left, right, compare):
"""Assumes left and right are sorted lists and
compare defines an ordering on the elements.
Returns a new sorted(by compare) list containing the
same elements as(left + right) would contain.
"""
result = []
i, j = 0, 0
while i < len(left) and j < len(right):
if compare(left[i], right[j]):
result.append(left[i])
i += 1
else :
result.append(right[j])
j += 1
while (i < len(left)):
result.append(left[i])
i += 1
while (j < len(right)):
result.append(right[j])
j += 1
return result
import operator
def mergeSort(L, compare = operator.lt):
"""Assumes L is a list, compare defines an ordering
on elements of L.
Returns a new sorted list containing the same elements as L"""
if len(L) < 2:
return L[: ]
else :
middle = len(L) //2
left = mergeSort(L[: middle], compare)
right = mergeSort(L[middle: ], compare)
return merge(left, right, compare)
哪里可能出错了?
另外,我认为麻省理工学院实施的关键区别在于它创建了一个新的列表,而不是改变原始列表。这使我很难理解mergesort,因为我发现CLRS的解释非常清楚,通过理解它可以根据不同层次的递归排序原始列表中最细小的组件(长度为1的列表排序),从而在旧列表本身中“存储”递归结果。
但是,再次思考,是否正确地说,MIT算法中的每个递归所返回的“结果”反过来又结合在一起?
谢谢!
你有一个堆栈跟踪? – khelwood
不幸的是,我还没有遇到过这个词。堆栈跟踪如何提供帮助? – kwotsin
堆栈跟踪是在程序出错时显示的消息,并告诉您问题出在哪里。 – khelwood