Go Program for Quick Sort Algorithm with Example
func quickSort(arr []int) []int.Examples
How to Think About It
Algorithm
Code
package main import "fmt" func quickSort(arr []int) []int { if len(arr) < 2 { return arr } pivot := arr[len(arr)-1] var left, right []int for _, v := range arr[:len(arr)-1] { if v < pivot { left = append(left, v) } else { right = append(right, v) } } left = quickSort(left) right = quickSort(right) return append(append(left, pivot), right...) } func main() { arr := []int{10, 7, 8, 9, 1, 5} sorted := quickSort(arr) fmt.Println(sorted) }
Dry Run
Let's trace the array [10, 7, 8, 9, 1, 5] through the quickSort function.
Initial call
arr = [10, 7, 8, 9, 1, 5], pivot = 5
Partition
left = [1], right = [10, 7, 8, 9]
Recursive call on left
quickSort([1]) returns [1]
Recursive call on right
quickSort([10, 7, 8, 9]) with pivot=9
Partition right
left = [7, 8], right = [10]
Recursive calls on right's parts
quickSort([7, 8]) returns [7, 8], quickSort([10]) returns [10]
Combine right parts
[7, 8] + [9] + [10] = [7, 8, 9, 10]
Combine all
[1] + [5] + [7, 8, 9, 10] = [1, 5, 7, 8, 9, 10]
| Call | Array | Pivot | Left | Right | Result |
|---|---|---|---|---|---|
| 1 | [10,7,8,9,1,5] | 5 | [1] | [10,7,8,9] | pending |
| 2 | [1] | 1 | [] | [] | [1] |
| 3 | [10,7,8,9] | 9 | [7,8] | [10] | pending |
| 4 | [7,8] | 8 | [7] | [] | [7,8] |
| 5 | [10] | 10 | [] | [] | [10] |
| 6 | combine right | [7,8,9,10] | |||
| 7 | combine all | [1,5,7,8,9,10] |
Why This Works
Step 1: Choosing a pivot
The pivot divides the array into smaller parts to sort separately, making sorting easier.
Step 2: Partitioning
Elements less than the pivot go to one side, others to the other side, organizing the array around the pivot.
Step 3: Recursion
Sorting the smaller parts recursively breaks the problem into simpler tasks until fully sorted.
Alternative Approaches
package main import "fmt" func quickSortInPlace(arr []int, low, high int) { if low < high { p := partition(arr, low, high) quickSortInPlace(arr, low, p-1) quickSortInPlace(arr, p+1, high) } } func partition(arr []int, low, high int) int { pivot := arr[high] i := low for j := low; j < high; j++ { if arr[j] < pivot { arr[i], arr[j] = arr[j], arr[i] i++ } } arr[i], arr[high] = arr[high], arr[i] return i } func main() { arr := []int{10, 7, 8, 9, 1, 5} quickSortInPlace(arr, 0, len(arr)-1) fmt.Println(arr) }
package main import ( "fmt" ) func quickSortConcurrent(arr []int) []int { if len(arr) < 2 { return arr } pivot := arr[len(arr)-1] var left, right []int for _, v := range arr[:len(arr)-1] { if v < pivot { left = append(left, v) } else { right = append(right, v) } } leftChan := make(chan []int) rightChan := make(chan []int) go func() { leftChan <- quickSortConcurrent(left) }() go func() { rightChan <- quickSortConcurrent(right) }() leftSorted := <-leftChan rightSorted := <-rightChan return append(append(leftSorted, pivot), rightSorted...) } func main() { arr := []int{10, 7, 8, 9, 1, 5} sorted := quickSortConcurrent(arr) fmt.Println(sorted) }
Complexity: O(n log n) average, O(n^2) worst case time, O(log n) average due to recursion stack, O(n) if not in-place space
Time Complexity
Quick sort divides the array and sorts parts recursively. Average case is O(n log n) because it splits roughly in half each time. Worst case is O(n^2) when pivot divides poorly.
Space Complexity
Extra space is used for recursion stack and temporary slices. In-place versions reduce space to O(log n) for recursion.
Which Approach is Fastest?
In-place quick sort is fastest in practice due to less memory use. Concurrent quick sort can be faster on large data with multiple CPU cores.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Simple recursive with slices | O(n log n) avg | O(n) | Easy to understand, small data |
| In-place quick sort | O(n log n) avg | O(log n) | Memory efficient, large data |
| Concurrent quick sort | Faster on multi-core | O(n) | Large data, parallel processing |