I had to implement the QuickSort algorithm for a homework in a language of my choice and I chose Python.
During the lectures, we've been told that QuickSort is memory efficient because it works in-place; i.e., it has no additional copies of parts of the input array for recursions.
With this in mind, I tried to implement the QuickSort algorithm in Python, but shortly afterwards realized that in order to write an elegant piece of code I would have to pass parts of the array to the function itself while recursing. Since Python creates new lists each time I do this, I have tried using Python3 (because it supports the nonlocal keyword). The following is my commented code.
def quicksort2(array):
# Create a local copy of array.
arr = array
def sort(start, end):
# Base case condition
if not start < end:
return
# Make it known to the inner function that we will work on arr
# from the outer definition
nonlocal arr
i = start + 1
j = start + 1
# Choosing the pivot as the first element of the working part
# part of arr
pivot = arr[start]
# Start partitioning
while j <= end:
if arr[j] < pivot:
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
i += 1
j += 1
temp = arr[start]
arr[start] = arr[i - 1]
arr[i - 1] = temp
# End partitioning
# Finally recurse on both partitions
sort(start + 0, i - 2)
sort(i, end)
sort(0, len(array) - 1)
Now, I'm not sure whether I did the job well or am I missing something. I have written a more Pythonic version of QuickSort but that surely doesn't work in-place because it keeps returning parts of the input array and concatenates them.
My question is, is this the way of doing it in Python? I have searched both Google and SO but haven't found a true in-place implementation of QuickSort, so I thought it'd be best to ask.