我遇到List index out of range
错误。
我还使用了 GeeksforGeeks 程序作为参考,但仍然遇到该错误。
如果不在Merge_Sort()
函数中使用它而运行它,我不会出错。
def Merge(arr, p, q, r):
n1 = q-p+1
n2 = r-q
L = [0]*n1
M = [0]*n2
for i in range(0, n1):
L[i] = arr[p+i-1]
for j in range(0, n2):
M[j] = arr[q+j]
i = 0
j = 0
for k in range(r-1):
if L[i] <= M[j]:
arr[k] = L[i]
i = i+1
else:
arr[k] = M[j]
j = j+1
def Merge_Sort(arr, p, r):
if p < r:
q = int((p+r)/2)
Merge_Sort(arr, p, q)
Merge_Sort(arr, q+1, r)
Merge(arr, p, q, r)
ar = [5, 3, 6, 1, 2, 9, 7, 8]
n = len(ar)
Merge_Sort(ar, 1, n)
print(ar)
Error:
line 14, in Merge
if L[i]<=M[j]:
IndexError: list index out of range
答案 0 :(得分:2)
代码不正确:索引值和切片边界以及其他错误也有些混乱:
数组索引从python中的0
开始,因此您应该调用Merge_sort(ar, 0, n)
切片长度n1
减1,应为n1 = q - p
递归测试应计算切片长度,并且仅对至少包含2个元素的切片进行递归。
合并循环不正确:您应该测试i
和j
是否都在切片内。一种有效的方法是用此测试替换比较:
if i < n1 and (j == n2 or L[i] <= M[j]):
合并循环应将k
从p
迭代到排除的r
,而不是从0
到排除的r
j
的增量代码未对齐,应该再缩进一步
考虑包括第一个索引而排除第二个索引要容易得多。网上有太多使用各种语言的教程都坚持使用其他约定,这总是给新手程序员带来困惑。
以下是经过纠正和简化的版本:
def Merge(arr, p, q, r):
n1 = q - p
n2 = r - q
L = arr[p : q]
M = arr[q : r]
i = 0
j = 0
for k in range(p, r):
if i < n1 and (j == n2 or L[i] <= M[j]):
arr[k] = L[i]
i = i + 1
else:
arr[k] = M[j]
j = j + 1
def Merge_Sort(arr, p, r):
if r - p >= 2:
q = (p + r) // 2
Merge_Sort(arr, p, q)
Merge_Sort(arr, q, r)
Merge(arr, p, q, r)
ar = [5, 3, 6, 1, 2, 9, 7, 8]
Merge_Sort(ar, 0, len(ar))
print(ar)
请注意,如果确保左切片始终至少与右切片一样大,则可以使用单个临时数组进一步简化MergeSort
函数:
def Merge(arr, p, q, r):
tmp = arr[p : q]
i = 0
n = q - p
while i < n:
if q == r or tmp[i] <= arr[q]:
arr[p] = tmp[i]
i += 1
p += 1
else:
arr[p] = arr[q]
q += 1
p += 1
def Merge_Sort(arr, p, r):
if r - p >= 2:
q = (p + r + 1) // 2
Merge_Sort(arr, p, q)
Merge_Sort(arr, q, r)
Merge(arr, p, q, r)
ar = [5, 3, 6, 1, 2, 9, 7, 8]
Merge_Sort(ar, 0, len(ar))
print(ar)
答案 1 :(得分:1)
您的代码不同于GeeksforGeeks代码。我更正了merge
函数以匹配它们。您需要三个循环:
L
或M
中取出较小的前几个元素,直到L
或M
为空L
中剩余的元素(如果有)M
中剩余的元素(如果有)您还需要一个变量来跟踪arr
中的当前索引(在这种情况下为k
)。
GeeksforGeeks代码:https://www.geeksforgeeks.org/merge-sort/
更正的python代码:
def Merge(arr, p, q, r):
n1 = q-p+1
n2 = r-q
L = [0]*n1
M = [0]*n2
for i in range(0,n1):
L[i] = arr[p+i]
for j in range(0, n2):
M[j] = arr[q+1+j]
i = 0
j = 0
# result index
k = p
# take smallest element until either L or M are empty
while i < n1 and j < n2:
if L[i]<=M[j]:
arr[k] = L[i]
i = i+1
else:
arr[k] = M[j]
j = j+1
k = k+1
# write remaining elements from L
while i < n1:
arr[k] = L[i]
i = i+1
k = k+1
# write remaining elements from M
while j < n2:
arr[k] = M[j]
j = j+1
k = k+1
def Merge_Sort(arr, p, r):
if p < r:
q = int((p+r)/2)
Merge_Sort(arr, p, q)
Merge_Sort(arr, q+1,r)
Merge(arr, p, q, r)
ar = [5,3,6,1,2,9,7,8]
n = len(ar)
Merge_Sort(ar,0,n-1)
print(ar)
如果只想使用一个循环,则可以将上述所有内容组合在一起(尽管不易读):
def Merge(arr, p, q, r):
n1 = q-p+1
n2 = r-q
L = [0]*n1
M = [0]*n2
for i in range(0,n1):
L[i] = arr[p+i]
for j in range(0, n2):
M[j] = arr[q+1+j]
i = 0
j = 0
for k in range(n1+n2):
if (i < n1 and j < n2 and L[i]<=M[j]) or j >= n2:
arr[p+k] = L[i]
i = i+1
else:
arr[p+k] = M[j]
j = j+1
def Merge_Sort(arr, p ,r):
if p < r:
q = int((p+r)/2)
Merge_Sort(arr, p, q)
Merge_Sort(arr, q+1,r)
Merge(arr, p, q, r)
ar = [5,3,6,1,2,9,7,8,]
n = len(ar)
Merge_Sort(ar,0,n-1)
print(ar)