简体   繁体   中英

QuickSort Python In-place index out of bounds error

Just writing a quickSort algorithm and I can't seem to break free from either an index out of bounds error or an infinite loop. Can someone point me in the right direction? Thanks in advance!

----------- Quick Sort --------------

def quickSort(lst):

    if len(lst) <= 1:
        return lst

    while len(lst) > 1:
        pivot = part(lst)
        quickSort(lst[ :pivot])
        quickSort(lst[pivot+1: ])
        return lst

def part(a):
    x = a[0]
    i = 1
    j = len(a)-1

    while (i <= j):
        while (i <= j) and (a[j] >= x):
            j -= 1
        while (i <= j) and (a[i] < x):
            i += 1
        if (i <= j) and a[i] > a[j]:
            temp = a[i]
            a[i] = a[j]
            a[j] = temp

    a[i], a[0] = a[0], a[i]     
    return i
while (i <= j) and (a[i] < x):
            i += 1

When i = j , and j being set to the len - 1 , the i+=1 will cause it to go out of bounds.

Before jump and debugging your code, you have to understand the idea behind quicksort. It is easy to understand what cause your "code error", IndexOutOfBound , but not so for "Logic error"

Quicksort

The key of Quick Sort algorithm is the partitioning. In partitioning, you usually take one pivot as your comparison point. In your case you choose index 0 as your pivot. Now imagine you have 3 logical partition in the array.

  • Pivot: Any number ( index: 0 )
  • Partition 1: Any numbers smaller than the pivot. ( index: 1..i )
  • Partition 2: Any numbers larger than the pivot. ( index: i..j )
  • Partition 3: The Unsorted numbers ( index: j..n-1 )

Your aim now is to take each of the numbers from Partition 3 into Partition 1 or 2. Then because Partition 3 will be emptied and we left with 2 partition. Swap the pivot with last element of partition 1. Then you have the following Partition 1 < Pivot < Partition 2

Next we deal with the Divide and Conquer technique in the Quicksort method.. In this method, you don't have to iteratively partition. Instead you just need to recursively call the Quicksort again for the each of the two new partitions which has been split by the pivot in the middle.

The reason why this quicksort can sort by only partitioning into two parts is because each time they partition, the pivot is actually in the sorted index of the array.

There are many implementation of Quicksort in the web. Don't get confused by looking them. Basically the idea is the same. (2 Partition with the pivot sorted). Some actually implement the partition from left to right, while others from right to left. In your case, You seems to mix the two direction together. Such that i goes to the right, and j goes to the left. So when doing so, you just have to be careful of this boundary, especially during the swapping.

In the past, I wrote Quicksort algorithm with one iterative loop in the partition methods (because it is much easier to understand when dealing with edge cases) and two recursive call in the quicksort algorithm.

Hope that helps you.

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