Lua - Quick Sort
Quick Sort is also to divide and conquer algorithm as similar to merge sort. In quick sort, an element is picked up as a pivot and list is divided into partitions around the pivot. Smaller elements than the pivot are in one partition and larger elements than the pivot are in another partition. This process is applied recursively on all partitions until list is completely sorted.
main.lua
-- function to create a partition
function partition(list, low, high)
-- last element is a pivot
local pivot = list[high]
local i = low - 1 -- index of first element
-- loop on elements of the partition
for j = low, high - 1 do
-- swap number if lower than pivot
if list[j] <= pivot then
i = i + 1
list[i], list[j] = list[j], list[i]
end
end
-- Swap list[i + 1] with list[high]
list[i + 1], list[high] = list[high], list[i + 1]
return i + 1 -- return the index to partition
end
function quick_sort(list, low, high)
if low < high then
-- Partition the list and get the partitioning index
local pi = partition(list, low, high)
-- Recursively quick sort elements before and after partition
quick_sort(list, low, pi - 1)
quick_sort(list, pi + 1, high)
end
return list
end
-- Example usage:
local numbers = {5, 1, 4, 2, 8}
local sorted_numbers = quick_sort(numbers, 1, #numbers)
print("Sorted list:", table.concat(sorted_numbers, ", ")) -- Output: Sorted list: 1, 2, 4, 5, 8
Output
When we run the above program, we will get the following output−
Sorted list: 1, 2, 4, 5, 8
Working of Quick Sort
Selection of Pivot − Pivot selection is an important step of quick sort algorithm. It can improve or degrade algorithm performance. Commonly, we can choose first or last element as a pivot or even a median of three numbers, first middle and last number. In example above, we've selected last element as a pivot.
Partitioning − During partitioning, we're arranging numbers in a fashion that smaller numbers comes before pivot and larger numbers comes after pivot. This makes pivot to be in final sorted position.
Recursive Calls − Now we're applying partitioning recursively on each sublist of elements smaller than pivot and greater than pivot.
Best Case or End Case − Recursive calls continues till the size of sublist becomes 1 or sublist is empty. As it is implicitly sorted in such a case.
partition function
partition − function is core of the quick sort algorithm. We're passing a list with low index and high index. Element at high index s treated as a pivot.
We're iterating through the sublist from low to high-1.
Smaller Element is swapped with next element.
Finally, pivot is swapped with element at i+1 to place it in correctly sorted position.
Index of the pivot is returned.
quick_sort function
quick_sort − function makes recursive calls. It checks if low index is less than high then it calls partition function to get the pivot.
Then recursive calls are made to sort the sublist before the pivot and after the pivot.
Time Complexity
Average Case - O(n log n) −, When a pivot divides list in two rougly equal halves.
Worst Case - O(n2) −,When a pivot selection causes unbalanced sublists. Like selecting highest or smallest number as pivot.
Best Case - O(n log n) −, When a pivot divides list in two exactly equal halves.
Space Complexity
O(log n) − Space complexity of quick sort is O(log n) due to recursive calls.
When to use Quick Sort
Quick sort is a very efficient sorting algorithm with a time complexity of O(n log n) −
Large Data Sets − Quick sort is generally preferred with large set of data.
Faster Sorting − Quick sort is normally faster than merge sort being in-memory sorting
Space Efficiency − Quick Sort is space savvy and is highly efficient.