简体   繁体   English

使用合并排序功能时获取列表索引超出范围错误

[英]Getting List Index out of Range Error while using Merge Sort function

I am getting List index out of range error. 我得到List index out of range错误。 I have also used GeeksforGeeks program as a reference but still got that error. 我也使用GeeksforGeeks程序作为参考,但仍然有错误。 I get no error when I run this without using it inside Merge_Sort() function. 当我在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

The code is incorrect: the is some confusion about index values and slice boundaries, and other mistakes too: 代码不正确:关于索引值和切片边界的一些混淆,以及其他错误:

  • array indices start at 0 in python, so you should call Merge_sort(ar, 0, n) 数组索引在python中从0开始,所以你应该调用Merge_sort(ar, 0, n)

  • the slice length n1 is off by one, it should be n1 = q - p 切片长度n1偏离1,应为n1 = q - p

  • the test for recursion should compute the slice length and only recurse for slices with at least 2 elements. 递归测试应该计算切片长度,并且只对具有至少2个元素的切片进行递归。

  • the merge loop is incorrect: you should test if i and j are both inside the slices. 合并循环不正确:您应该测试ij是否都在切片内。 An efficient way to do this is to replace the comparison with this test: 一种有效的方法是用这个测试替换比较:

     if i < n1 and (j == n2 or L[i] <= M[j]): 
  • the merge loop should iterate for k from p to r excluded, not from 0 to r excluded 合并循环应该迭代kpr排除,而不是从0r排除

  • the increment code for j is misaligned, it should be indented one more step j的增量代码未对齐,应该再缩进一步

It is much simpler to consider the first index to be included and the second to be excluded. 考虑要包括的第一个索引和要排除的第二个索引要简单得多。 There are far too many tutorials in the net in various languages that insist on other conventions, invariably causing confusion for newbie programmers. 网络中有太多的教程在各种语言中坚持其他惯例,总是会给新手程序员造成混乱。

Here is a corrected and simplified version: 这是一个更正和简化的版本:

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)

Note that you can further simplify the MergeSort function with a single temporary array if you ensure that the left slice is always at least as large as the right slice: 请注意,如果确保左切片始终至少与右切片一样大,则可以使用单个临时数组进一步简化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)

Your code differs from the GeeksforGeeks code. 您的代码与GeeksforGeeks代码不同。 I corrected the merge function to match theirs. 我更正了merge功能以匹配他们的功能。 You need three loops: 你需要三个循环:

  1. Take the smaller of the first elements from L or M until either L or M is empty LM取出较小的第一个元素,直到LM为空
  2. Append the elements remaining in L (if any) 附加L剩余的元素(如果有的话)
  3. Append the elements remaining in M (if any) 附加M剩余的元素(如果有的话)

You also need a variable that tracks the current index in arr ( k in this case). 您还需要一个跟踪arr当前索引的变量(在本例中为k )。

GeeksforGeeks code: https://www.geeksforgeeks.org/merge-sort/ GeeksforGeeks代码: https ://www.geeksforgeeks.org/merge-sort/

Corrected python code: 更正了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)

If you only want to use one loop you can combine all of the above like so (takes away from the readability though): 如果您只想使用一个循环,您可以将所有上述内容组合在一起(尽管可读性有所不同):

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM