I am totally new to python and I am trying to implement quicksort in it. Could someone please help me complete my code?
I do not know how to concatenate the three arrays and printing them.
def sort(array=[12,4,5,6,7,3,1,15]):
less = []
equal = []
greater = []
if len(array) > 1:
pivot = array[0]
for x in array:
if x < pivot:
less.append(x)
if x == pivot:
equal.append(x)
if x > pivot:
greater.append(x)
sort(less)
sort(pivot)
sort(greater)
There is another concise and beautiful version
Let me explain the above codes for details
pick the first element of array
arr[0]
as pivot[arr[0]]
qsort
those elements of array which are less than pivot withList Comprehension
qsort([x for x in arr[1:] if x < arr[0]])
qsort
those elements of array which are larger than pivot withList Comprehension
qsort([x for x in arr[1:] if x >= arr[0]])
The algorithm contains two boundaries, one having elements less than the pivot (tracked by index "j") and the other having elements greater than the pivot (tracked by index "i").
In each iteration, a new element is processed by incrementing j.
Invariant:-
If the invariant is violated, ith and jth elements are swapped, and i is incremented.
After all elements have been processed, and everything after the pivot has been partitioned, the pivot element is swapped with the last element smaller than it.
The pivot element will now be in its correct place in the sequence. The elements before it will be less than it and the ones after it will be greater than it, and they will be unsorted.
Selecting a pivot
A "good" pivot will result in two sub-sequences of roughly the same size. Deterministically, a pivot element can either be selected in a naive manner or by computing the median of the sequence.
A naive implementation of selecting a pivot will be the first or last element. The worst-case runtime in this case will be when the input sequence is already sorted or reverse sorted, as one of the subsequences will be empty which will cause only one element to be removed per recursive call.
A perfectly balanced split is achieved when the pivot is the median element of the sequence. There are an equal number of elements greater than it and less than it. This approach guarantees a better overall running time, but is much more time-consuming.
A non-deterministic/random way of selecting the pivot would be to pick an element uniformly at random. This is a simple and lightweight approach that will minimize worst-case scenario and also lead to a roughly balanced split. This will also provide a balance between the naive approach and the median approach of selecting the pivot.
functional programming aproach
Quick sort without additional memory (in place)
Usage:
If I search "python quicksort implementation" in Google, this question is the first result to pop up. I understand that the initial question was to "help correct the code" but there already are many answers that disregard that request: the currently second most voted one, the horrendous one-liner with the hilarious "You are fired" comment and, in general, many implementations that are not in-place (i.e. use extra memory proportional to input list size). This answer provides an in-place solution but it is for
python 2.x
. So, below follows my interpretation of the in-place solution from Rosetta Code which will work just fine forpython 3
too:And if you are willing to forgo the in-place property, below is yet another version which better illustrates the basic ideas behind quicksort. Apart from readability, its other advantage is that it is stable (equal elements appear in the sorted list in the same order that they used to have in the unsorted list). This stability property does not hold with the less memory-hungry in-place implementation presented above.