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.

Advertisements