簡體   English   中英

python IndexError中的合並排序

[英]merge sort in python IndexError

在我使用 python 的合並排序實現中,運行時發生錯誤

IndexError: list assignment index out of range

這是代碼:

#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  

歸並排序的方法

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)

司機

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

運行代碼時出現錯誤,指出IndexError: list assignment index out of range

您的代碼中有一些錯誤,固定版本如下所示(固定行已注釋):

合並

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  

歸並排序

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)

和最終的函數調用:

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

您將數組的長度作為第二個參數傳遞給merge ,但merge函數似乎期望對范圍中的最后一個元素的索引進行排序。

這個 API 很經典,但選擇不當,因為你不能指定一個空范圍,而且它不太規則,需要一些額外的調整( + 1- 1子數組大小等)。 您應該修改代碼,使其high到要排序的范圍之后的第一個元素的索引。

merge函數還有其他問題:

  • 子數組大小的計算不正確
  • 你在while循環外增加kk = k + 1應該在更深的層次上增加。
  • 最后一個循環應該使用j而不是i作為索引。
  • 此實現使用遞歸,而不是遞歸

這是一個修改后的版本:

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