简体   繁体   English

python IndexError中的合并排序

[英]merge sort in python IndexError

In my merge sort implementation using python, run time an error occurred as在我使用 python 的合并排序实现中,运行时发生错误

IndexError: list assignment index out of range

Here is the code:这是代码:

#merge
def merge(array, low, mid, high):
   n1 = mid - low + 1
   n2 = high - mid
   ll = [] * n1
   rr = [] * n2
   for i in range(n1):
      ll[i] = array[low + i]
   for j in range(n2):
      rr[j] = array[mid + 1 + j]

   (i, j) = (0, 0)
   k = low

   while i < n1 and j < n2:
      if ll[i] <= rr[j]:
         array[k] = ll[i]
         i = i + 1
      else:
         array[k] = rr[j]
         j = j + 1
   k = k + 1
   #for remaining members of the lists
   while i < n1:
      array[k] = ll[i]
      i = i + 1
      k = k + 1                

   while i < n2:
      array[k] = rr[j]
      j = j + 1
      k = k + 1  

method for merge sort归并排序的方法

def mergesort(array, low, high):
   if low < high:
      mid = low + (high - low) // 2

      #recurrence
      mergesort(array, low, mid)
      mergesort(array, mid + 1, high)
      merge(array, low, mid, high)

driver司机

array = [ 74, 32, 89, 55, 21, 64 ]
mergesort(array, 0, len(array))    

while running the code am getting an error that says IndexError: list assignment index out of range运行代码时出现错误,指出IndexError: list assignment index out of range

There are some mistakes in your code, fixed version looks like this (fixed lines are commented):您的代码中有一些错误,固定版本如下所示(固定行已注释):

merge合并

def merge(array, low, mid, high):
    n1 = mid - low + 1
    n2 = high - mid
    ll = [0] * n1  # here
    rr = [0] * n2  # here

    for i in range(n1):
        ll[i] = array[low + i]
    for j in range(n2):
        rr[j] = array[mid + 1 + j]

    i, j = 0, 0
    k = low

    while i < n1 and j < n2 :
        if ll[i] <= rr[j]:
           array[k] = ll[i]
           i += 1
        else:
           array[k] = rr[j]
           j += 1
        k += 1
    while i < n1:
       array[k] = ll[i]
       i += 1
       k += 1

    while j < n2:  # here
      array[k] = rr[j]
      j += 1
      k += 1  

mergesort归并排序

def mergesort(array, low, high):
   if low < high:
        mid = (low + (high - 1)) // 2  # here

        mergesort(array, low, mid)
        mergesort(array, mid + 1, high)
        merge(array, low, mid, high)

and final function call:和最终的函数调用:

array = [74 , 32 , 89 , 55 , 21 , 64]
mergesort(array , 0 , len(array) - 1)  # here

You pass the length of the array as the second argument to merge , but the merge function seems to expect the index of the last element in the range to be sorted.您将数组的长度作为第二个参数传递给merge ,但merge函数似乎期望对范围中的最后一个元素的索引进行排序。

This API is classic but poorly chosen as you cannot specify an empty range and it is less regular, requiring some extra adjustments ( + 1 and - 1 on subarray sizes etc.).这个 API 很经典,但选择不当,因为你不能指定一个空范围,而且它不太规则,需要一些额外的调整( + 1- 1子数组大小等)。 You should modify the code so high is the index of the first element after the range to be sorted.您应该修改代码,使其high到要排序的范围之后的第一个元素的索引。

There are other problems in the merge function: merge函数还有其他问题:

  • the computation for the subarray sizes is incorrect子数组大小的计算不正确
  • you increment k outside the while loop: k = k + 1 should be incremented in level deeper.你在while循环外增加kk = k + 1应该在更深的层次上增加。
  • the last loop should use j instead of i as the index.最后一个循环应该使用j而不是i作为索引。
  • this implementation uses recursion , not recurrence此实现使用递归,而不是递归

Here is a modified version:这是一个修改后的版本:

def merge(array, low, mid, high):
   n1 = mid - low
   n2 = high - mid
   ll = [] * n1
   rr = [] * n2
   for i in range(n1):
      ll[i] = array[low + i]
   for j in range(n2):
      rr[j] = array[mid + j]

   i = 0
   j = 0
   k = low

   while i < n1 and j < n2:
      if ll[i] <= rr[j]:
         array[k] = ll[i]
         i = i + 1
      else:
         array[k] = rr[j]
         j = j + 1
      k = k + 1

   #copy the remaining members of the lists
   while i < n1:
      array[k] = ll[i]
      i = i + 1
      k = k + 1                

   while j < n2:
      array[k] = rr[j]
      j = j + 1
      k = k + 1  

def mergesort(array, low, high):
   if high - low > 1:
      mid = low + (high - low) // 2

      #recursion
      mergesort(array, low, mid)
      mergesort(array, mid, high)
      merge(array, low, mid, high)

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

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