简体   繁体   中英

Getting recursion wrong in Quick Sort

I have seen numerous cases of Quicksort implementation in Python related doubts here on stack, but could not find what I am looking for. My question is specific to the implementation below:

# Implementation of Quick-Sort algorithm in Python as taught in the course: Design and Analysis of Algorithms on Coursera

def QuickSort(array, length):
    if (length == 1 or length == 0):
        return

    numComparisons = 0
    numComparisons = numComparisons + length - 1

    print('array to be sorted is: ', array) 
    pivot = ChoosePivot(array,length)
    print('Pivot is: ', pivot)
    left    = 0
    right = length

    pivotIndex = Partition(array,left,right)

    print('array after partitioning step is: ', array)
    print('Pivot Index in the array is:', pivotIndex)

    QuickSort(array[:pivotIndex], pivotIndex)
    QuickSort(array[pivotIndex+1:], length-pivotIndex-1)
    print('Sorting is done! Final array is:', array)

    return numComparisons,array

def ChoosePivot(array,length):
    #For the first part of the question, choosing first element of array as pivot element
    return (array[0])

def Swap(array,elementLeft,elementRight):
    tmp = array[elementLeft]
    array[elementLeft] = array[elementRight]
    array[elementRight] = tmp
    return array

def Partition(array,left,right):
    pivot = array[left]
    i = left + 1
    j = left + 1    

    for j in range(right):
        if (array[j] < pivot):
            Swap(array,j,i)
            i = i + 1

    # send pivot to the correct position
    array = Swap(array,left,i-1)
    return (i-1)

array = [7,5,4,6,1,15,12]
numElements = len(array)  
numComp, array = QuickSort(array,numElements)
print('Total number of comparisons',numComp)
print(array)

So the idea is to use the first element of the array as a pivot element and carry out the partitioning on the basis of the pivot element. (Not explaining the algorithm here as I don't think it is of great importance here)

On running the above code I get the following output:

('array to be sorted is: ', [7, 5, 4, 6, 1, 15, 12])
('Pivot is: ', 7)
('array after partitioning step is: ', [1, 5, 4, 6, 7, 15, 12])
('Pivot Index in the array is:', 4)
('array to be sorted is: ', [1, 5, 4, 6])
('Pivot is: ', 1) 
('array after partitioning step is: ', [1, 5, 4, 6])
('Pivot Index in the array is:', 0)
('array to be sorted is: ', [5, 4, 6])
('Pivot is: ', 5)
--->('array after partitioning step is: ', [4, 5, 6])
--->('Pivot Index in the array is:', 1)
--->('Sorting is done! Final array is:', [4, 5, 6])
--->('Sorting is done! Final array is:', [1, 5, 4, 6])
('array to be sorted is: ', [15, 12])
('Pivot is: ', 15)
('array after partitioning step is: ', [12, 15])
('Pivot Index in the array is:', 1)
--->('Sorting is done! Final array is:', [12, 15])
--->('Sorting is done! Final array is:', [1, 5, 4, 6, 7, 15, 12])
('Total number of comparisons', 6)
[1, 5, 4, 6, 7, 15, 12]

So, I am not able to understand as to why there is a change in the positions of the elements back to the original one even after it shows that sorting has taken place (Look at the lines marked with '--->' in front).

I feel that it has to do with the way I am passing the arrays. Any help would be appreciated and If more details are required, let me know

Try to change:

array = Swap(array,left,i-1)

to:

Swap(array,left,i-1)

when you assign a value to the array inside a function, python creates a new array and you lose the reference to the original one

EDIT: I think the problem is the function call to QuickSort for the same reason, pass the array with start/end indexes instead of cutting it. another problem is in the partition function, you should add left to j.

this is the complete code:

def QuickSort(array, start, end, length):
    if (end - start <=1):
        return

    numComparisons = 0
    numComparisons = numComparisons + length - 1

    print('array to be sorted is: ', array[start:end]) 
    pivot = ChoosePivot(array[start:end],length)
    print('Pivot is: ', pivot)
    left    = start
    right = end

    pivotIndex = Partition(array,left,right)

    print('array after partitioning step is: ', array[start:end])
    print('Pivot Index in the array is:', pivotIndex)

    QuickSort(array,start, pivotIndex, pivotIndex)
    QuickSort(array, pivotIndex+1, end, length-pivotIndex-1)
    print('Sorting is done! Final array is:', array[start:end])

    return numComparisons,array

def ChoosePivot(array,length):
    #For the first part of the question, choosing first element of array as pivot element
    return (array[0])

def Swap(array,elementLeft,elementRight):
    tmp = array[elementLeft]
    array[elementLeft] = array[elementRight]
    array[elementRight] = tmp
    return array

def Partition(array,left,right):
    pivot = array[left]
    i = left + 1
    j = left + 1    

    for j in range(right):
        if (array[left+j] < pivot):
            Swap(array,left+j,i)
            i = i + 1

    # send pivot to the correct position
    Swap(array,left,i-1)
    return (i-1)

array = [7,5,4,6,1,15,12]
numElements = len(array)  
numComp, array = QuickSort(array,0,6,numElements)
print('Total number of comparisons',numComp)
print(array)

Simplified single function version:

def quicksort(a, lo, hi):
    if(lo < hi):
        pivot = a[lo]
        i = lo+1
        for j in range(lo+1, hi+1):
            if a[j] < pivot:
                a[i],a[j] = a[j],a[i]
                i += 1
        i -= 1
        a[i],a[lo] = a[lo],a[i]
        quicksort(a, lo, i-1)
        quicksort(a, i+1, hi)

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