0
0
DSA Goprogramming

Quick Sort Partition Lomuto and Hoare in DSA Go

Choose your learning style9 modes available
Mental Model
Partition divides an array into two parts around a pivot so smaller values go left and larger go right. Lomuto and Hoare are two ways to do this.
Analogy: Imagine sorting books on a shelf by height: Lomuto picks one book as a divider and moves shorter books left and taller right, while Hoare uses two hands from both ends to swap books until they meet.
Array: [5, 3, 8, 4, 2]
Pivot: 2 (Lomuto picks last element)
Indexes: i and j move to rearrange

Initial:
[5, 3, 8, 4, 2]
 i= -1, j=0

After partition:
[2, 3, 8, 4, 5]
Pivot at index 0
Dry Run Walkthrough
Input: array: [5, 3, 8, 4, 2], partition using Lomuto and Hoare
Goal: Show how Lomuto and Hoare partition rearrange the array around the pivot
Step 1: Lomuto: set pivot as last element (2), i = -1
[5, 3, 8, 4, 2]
i = -1, j = 0
Why: Pivot chosen to compare others against; i tracks smaller elements
Step 2: Lomuto: j=0 (5 > 2), no swap, i stays -1
[5, 3, 8, 4, 2]
i = -1, j = 1
Why: 5 is bigger than pivot, so no move
Step 3: Lomuto: j=1 (3 > 2), no swap, i stays -1
[5, 3, 8, 4, 2]
i = -1, j = 2
Why: 3 is bigger than pivot, no move
Step 4: Lomuto: j=2 (8 > 2), no swap, i stays -1
[5, 3, 8, 4, 2]
i = -1, j = 3
Why: 8 is bigger than pivot, no move
Step 5: Lomuto: j=3 (4 > 2), no swap, i stays -1
[5, 3, 8, 4, 2]
i = -1, j = 4
Why: 4 is bigger than pivot, no move
Step 6: Lomuto: swap pivot (2) with element at i+1 (5)
[2, 3, 8, 4, 5]
i = 0
Why: Place pivot in correct position so left are smaller
Step 7: Hoare: set pivot as first element (5), i=0, j=5
[5, 3, 8, 4, 2]
i=0, j=5
Why: Pivot chosen at start; i and j move inward
Step 8: Hoare: move j left while arr[j] > pivot (j moves from 5 to 4, arr[4]=2 <= 5 stops at j=4)
[5, 3, 8, 4, 2]
i=0, j=4
Why: Find element smaller than pivot from right
Step 9: Hoare: move i right while arr[i] < pivot (3 < 5 at i=1, 8 > 5 stops at i=2)
[5, 3, 8, 4, 2]
i=2, j=4
Why: Find element bigger than pivot from left
Step 10: Hoare: swap arr[i] (8) and arr[j] (2)
[5, 3, 2, 4, 8]
i=2, j=4
Why: Swap out-of-place elements to correct sides
Step 11: Hoare: move j left (j=3, arr[3]=4 < 5 stops), move i right (i=3, arr[3]=4 < 5 moves to i=3)
[5, 3, 2, 4, 8]
i=3, j=3
Why: Continue scanning inward
Step 12: Hoare: i >= j (3 >= 3), partition ends, return j=3
[5, 3, 2, 4, 8]
Why: Pointers crossed, partition done
Result:
Lomuto partition result: [2, 3, 8, 4, 5], pivot index 0
Hoare partition result: [5, 3, 2, 4, 8], partition index 3
Annotated Code
DSA Go
package main

import "fmt"

// Lomuto partition scheme
func lomutoPartition(arr []int, low, high int) int {
    pivot := arr[high] // pivot is last element
    i := low - 1       // i tracks smaller element index
    for j := low; j < high; j++ {
        if arr[j] <= pivot {
            i++
            arr[i], arr[j] = arr[j], arr[i] // swap smaller element to front
        }
    }
    arr[i+1], arr[high] = arr[high], arr[i+1] // place pivot after smaller elements
    return i + 1
}

// Hoare partition scheme
func hoarePartition(arr []int, low, high int) int {
    pivot := arr[low] // pivot is first element
    i := low - 1
    j := high + 1
    for {
        for {
            j--
            if arr[j] <= pivot {
                break
            }
        }
        for {
            i++
            if arr[i] >= pivot {
                break
            }
        }
        if i < j {
            arr[i], arr[j] = arr[j], arr[i] // swap out-of-place elements
        } else {
            return j
        }
    }
}

func main() {
    arr1 := []int{5, 3, 8, 4, 2}
    p1 := lomutoPartition(arr1, 0, len(arr1)-1)
    fmt.Printf("Lomuto partition result: %v, pivot index %d\n", arr1, p1)

    arr2 := []int{5, 3, 8, 4, 2}
    p2 := hoarePartition(arr2, 0, len(arr2)-1)
    fmt.Printf("Hoare partition result: %v, partition index %d\n", arr2, p2)
}
pivot := arr[high] // pivot is last element
select pivot for Lomuto partition
i := low - 1 // i tracks smaller element index
initialize i before low
if arr[j] <= pivot { i++; swap arr[i], arr[j] }
move smaller or equal elements left
swap arr[i+1], arr[high]
place pivot after smaller elements
pivot := arr[low] // pivot is first element
select pivot for Hoare partition
j-- until arr[j] <= pivot
move j left to find smaller or equal element
i++ until arr[i] >= pivot
move i right to find bigger or equal element
if i < j { swap arr[i], arr[j] } else { return j }
swap out-of-place elements or end partition
OutputSuccess
Lomuto partition result: [2 3 8 4 5], pivot index 0 Hoare partition result: [5 3 2 4 8], partition index 3
Complexity Analysis
Time: O(n) because each partition scans the array once with pointers moving inward
Space: O(1) because partitioning is done in place without extra arrays
vs Alternative: Compared to naive partition that might use extra arrays, these in-place methods save space and are faster
Edge Cases
array with all equal elements
Lomuto places pivot at end; Hoare partitions but may return low index; both handle gracefully
DSA Go
if arr[j] <= pivot { i++; swap arr[i], arr[j] }
array with single element
partition returns the single index without swaps
DSA Go
for j := low; j < high; j++ { ... }
empty array
partition functions are not called or return immediately
DSA Go
main driver controls input size before calling partition
When to Use This Pattern
When you see a problem asking to sort or rearrange around a pivot quickly, think of Lomuto or Hoare partition schemes as the core step in quicksort.
Common Mistakes
Mistake: Using Lomuto but forgetting to swap the pivot at the end
Fix: Always swap pivot with element at i+1 after scanning
Mistake: In Hoare, moving pointers incorrectly causing infinite loops
Fix: Ensure inner loops move pointers until correct condition before swapping or returning
Summary
Partitions an array around a pivot so smaller elements go left and larger go right.
Use when implementing quicksort to efficiently divide the array for recursive sorting.
The key insight is how pointers move and swap elements to place the pivot correctly without extra space.