quick sort
This commit is contained in:
parent
4431b6638f
commit
1f81f4cb45
2 changed files with 73 additions and 0 deletions
63
sorting/quick.go
Normal file
63
sorting/quick.go
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
package sorting
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func exch[T any](items []T, a int, b int) {
|
||||||
|
items[a], items[b] = items[b], items[a]
|
||||||
|
}
|
||||||
|
|
||||||
|
func partition[T any](items []T, lo int, hi int, less func(a, b T) bool) int {
|
||||||
|
i, j := lo, hi+1
|
||||||
|
v := items[lo]
|
||||||
|
|
||||||
|
for {
|
||||||
|
for i++; less(items[i], v); i++ {
|
||||||
|
if i == hi {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for j--; less(v, items[j]); j-- {
|
||||||
|
if j == lo {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if i >= j {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
exch(items, i, j)
|
||||||
|
}
|
||||||
|
exch(items, j, lo)
|
||||||
|
|
||||||
|
return j
|
||||||
|
}
|
||||||
|
|
||||||
|
func doQuickSort[T any](items []T, lo int, hi int, less func(a, b T) bool) {
|
||||||
|
if hi-lo <= 15 {
|
||||||
|
Insertion(items[lo:hi+1], less)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if lo >= hi {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mi := partition(items, lo, hi, less)
|
||||||
|
doQuickSort(items, lo, mi-1, less)
|
||||||
|
doQuickSort(items, mi+1, hi, less)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func Quick[T any](items []T, less func(a, b T) bool) {
|
||||||
|
|
||||||
|
// We shuffle array to prevent worst case scenario when array already sorted.
|
||||||
|
// Without shuffling we get O(n^2) time. Another variant how to prevent
|
||||||
|
// such performance drop is to compute median element in partition function.
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
rand.Shuffle(len(items), func(i, j int) { items[i], items[j] = items[j], items[i] })
|
||||||
|
doQuickSort(items, 0, len(items)-1, less)
|
||||||
|
}
|
|
@ -63,3 +63,13 @@ func BenchmarkBottomUpMerge(b *testing.B) {
|
||||||
BenchmarkSort(10000, BottomUpMerge[int])
|
BenchmarkSort(10000, BottomUpMerge[int])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestQuick(t *testing.T) {
|
||||||
|
CheckSliceSorter(Quick[int])
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkQuick(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
BenchmarkSort(10000, Quick[int])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue