Sorting
Quick Sort (Lomuto)
Choose the last item as a pivot, partition smaller values to its left, then recurse on the two sides.
Algorithm
Basic Implementation
basic.rb
def partition(arr, low, high)
pivot = arr[high]
i = low - 1
(low...high).each do |j|
if arr[j] <= pivot
i += 1
arr[i], arr[j] = arr[j], arr[i]
end
end
arr[i + 1], arr[high] = arr[high], arr[i + 1]
i + 1
end
def quick_sort(arr, low, high)
if low < high
pivot_index = partition(arr, low, high)
quick_sort(arr, low, pivot_index - 1)
quick_sort(arr, pivot_index + 1, high)
end
end
arr = [4, 1, 5, 2, 3]
quick_sort(arr, 0, arr.length - 1)
puts arr.inspect
Complexity
- Time: O(n^2) worst, O(n log n) average
- Space: O(log n) average call stack
- Stable: no
Implementation notes
quick_sort(arr, low, high)mutates the same RubyArray; it does not return a new sorted array.- The recursion guard is
if low < high, so empty and one-element ranges stop without callingpartition. partition(arr, low, high)chooses the last slot as the pivot withpivot = arr[high].i = low - 1marks the end of the<= pivotside, and(low...high).eachscansjup to but not including the pivot slot.- When
arr[j] <= pivot, Ruby parallel assignmentarr[i], arr[j] = arr[j], arr[i]swaps two array slots in place. - After the scan,
arr[i + 1], arr[high] = arr[high], arr[i + 1]places the pivot at its final index and returnsi + 1. - The trace for
[4, 1, 5, 2, 3]keeps4and5on the right of pivot3, swaps1and2left, then places3at index2. - The replay then summarizes recursive calls on
[1, 2]and[4, 5]; it does not include a separate bad-pivot degradation case. puts arr.inspectprints the mutated array as[1, 2, 3, 4, 5].
pivot
The final element is moved to the boundary between smaller and larger values.
partition
One scan rearranges the current range before the recursive calls.