简体   繁体   中英

merge sort in python IndexError

In my merge sort implementation using python, run time an error occurred as

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

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.

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.). You should modify the code so high is the index of the first element after the range to be sorted.

There are other problems in the merge function:

  • the computation for the subarray sizes is incorrect
  • you increment k outside the while loop: k = k + 1 should be incremented in level deeper.
  • the last loop should use j instead of i as the index.
  • 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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