文章目录
-
- 快速排序
- 插入排序
- 希尔排序
- 归并排序
- 选择排序
- 冒泡排序
- 堆排序
- 桶排序
- 代码验证
快速排序
func FastSort(a []int) {
if len(a) < 2 {
return
}
pivot := a[0]
i := 1
for j := 1; j < len(a); j++ {
if a[j] < pivot {
a[i], a[j] = a[j], a[i]
i++
}
}
a[0], a[i-1] = a[i-1], a[0]
FastSort(a[:i-1])
FastSort(a[i:])
}
插入排序
func InsertSort(a []int) {
for i := 1; i < len(a); i++ {
for j := i; j > 0; j-- {
if a[j] < a[j-1] {
a[j], a[j-1] = a[j-1], a[j]
}
}
}
}
希尔排序
func ShellSort(a []int) {
h := 1
for h < len(a)/3 {
h = h*3 + 1
}
for h >= 1 {
for i := h; i < len(a); i++ {
for j := i; j >= h && a[j] < a[j-h]; j -= h {
a[j], a[j-h] = a[j-h], a[j]
}
}
h /= 3
}
}
归并排序
func MergeSort(a []int) {
mergeSort(a, 0, len(a)-1)
}
func mergeSort(a []int, l, r int) {
if l >= r {
return
}
mid := (l + r) / 2
mergeSort(a, l, mid)
mergeSort(a, mid+1, r)
merge(a, l, mid, r)
}
func merge(a []int, l, mid, r int) {
tmp := make([]int, r-l+1)
i, j, k := l, mid+1, 0
for i <= mid && j <= r {
if a[i] < a[j] {
tmp[k] = a[i]
i++
} else {
tmp[k] = a[j]
j++
}
k++
}
for i <= mid {
tmp[k] = a[i]
i++
k++
}
for j <= r {
tmp[k] = a[j]
j++
k++
}
for i := 0; i < len(tmp); i++ {
a[l+i] = tmp[i]
}
}
选择排序
func SelectSort(a []int) {
for i := 0; i < len(a); i++ {
min := i
for j := i + 1; j < len(a); j++ {
if a[j] < a[min] {
min = j
}
}
a[i], a[min] = a[min], a[i]
}
}
冒泡排序
func BubbleSort(a []int) {
for i := 0; i < len(a); i++ {
for j := 0; j < len(a)-i-1; j++ {
if a[j] > a[j+1] {
a[j], a[j+1] = a[j+1], a[j]
}
}
}
}
堆排序
func HeapSort(a []int) {
for i := len(a) / 2; i >= 0; i-- {
heapAdjust(a, i, len(a))
}
for i := len(a) - 1; i > 0; i-- {
a[0], a[i] = a[i], a[0]
heapAdjust(a, 0, i)
}
}
func heapAdjust(a []int, i, length int) {
tmp := a[i]
for k := 2*i + 1; k < length; k = 2*k + 1 {
if k+1 < length && a[k] < a[k+1] {
k++
}
if a[k] > tmp {
a[i] = a[k]
i = k
} else {
break
}
}
a[i] = tmp
}
桶排序
func BucketSort(a []int) {
if a == nil {
return
}
min := a[0]
max := min
for _, i := range a {
if i < min {
min = i
}
if i > max {
max = i
}
}
total := (max-min)/len(a) + 1
buckets := make([][]int, total)
for i := 0; i < len(a); i++ {
idx := (a[i] - min) / len(a)
buckets[idx] = append(buckets[idx], a[i])
}
for i := 0; i < len(buckets); i++ {
InsertSort(buckets[i])
}
k := 0
for i := 0; i < len(buckets); i++ {
for j := 0; j < len(buckets[i]); j++ {
a[k] = buckets[i][j]
k++
}
}
}
代码验证
package sort
import (
"math/rand"
"testing"
)
func TestSort(t *testing.T) {
var a []int
for i := 10; i > 0; i-- {
a = append(a, rand.Intn(65536)%1000)
}
assert := func(a, b []int) bool {
if len(a) != len(b) {
return false
}
for i := 0; i < len(a); i++ {
if a[i] != b[i] {
return false
}
}
return true
}
expect := make([]int, len(a))
copy(expect, a)
InsertSort(expect)
t.Logf("before sort: %v\n", a)
t.Logf("expect: %v\n", expect)
t.Run("FastSort", func(t *testing.T) {
b := make([]int, len(a))
copy(b, a)
FastSort(b)
if !assert(b, expect) {
t.Errorf("FastSort: %v\n", b)
}
})
t.Run("ShellSort", func(t *testing.T) {
b := make([]int, len(a))
copy(b, a)
ShellSort(b)
if !assert(b, expect) {
t.Errorf("ShellSort: %v\n", b)
}
})
t.Run("MergeSort", func(t *testing.T) {
b := make([]int, len(a))
copy(b, a)
MergeSort(b)
if !assert(b, expect) {
t.Errorf("MergeSort: %v\n", b)
}
})
t.Run("SelectSort", func(t *testing.T) {
b := make([]int, len(a))
copy(b, a)
SelectSort(b)
if !assert(b, expect) {
t.Errorf("SelectSort: %v\n", b)
}
})
t.Run("BubbleSort", func(t *testing.T) {
b := make([]int, len(a))
copy(b, a)
BubbleSort(b)
if !assert(b, expect) {
t.Errorf("BubbleSort: %v\n", b)
}
})
t.Run("HeapSort", func(t *testing.T) {
b := make([]int, len(a))
copy(b, a)
HeapSort(b)
if !assert(b, expect) {
t.Errorf("HeapSort: %v\n", b)
}
})
t.Run("BucketSort", func(t *testing.T) {
b := make([]int, len(a))
copy(b, a)
BucketSort(b)
if !assert(b, expect) {
t.Errorf("BucketSort: %v\n", b)
}
})
t.Run("InsertSort", func(t *testing.T) {
b := make([]int, len(a))
copy(b, a)
InsertSort(b)
if !assert(b, expect) {
t.Errorf("InsertSort: %v\n", b)
}
})
}
func BenchmarkSort(b *testing.B) {
var a []int
for i := 10000; i > 0; i-- {
a = append(a, rand.Intn(1000000))
}
b.Run("InsertSort", func(b *testing.B) {
c := make([]int, len(a))
copy(c, a)
b.ResetTimer()
for i := 0; i < b.N; i++ {
InsertSort(c)
}
})
b.Run("ShellSort", func(b *testing.B) {
c := make([]int, len(a))
copy(c, a)
b.ResetTimer()
for i := 0; i < b.N; i++ {
ShellSort(c)
}
})
b.Run("MergeSort", func(b *testing.B) {
c := make([]int, len(a))
copy(c, a)
b.ResetTimer()
for i := 0; i < b.N; i++ {
MergeSort(c)
}
})
b.Run("SelectSort", func(b *testing.B) {
c := make([]int, len(a))
copy(c, a)
b.ResetTimer()
for i := 0; i < b.N; i++ {
SelectSort(c)
}
})
b.Run("BubbleSort", func(b *testing.B) {
c := make([]int, len(a))
copy(c, a)
b.ResetTimer()
for i := 0; i < b.N; i++ {
BubbleSort(c)
}
})
b.Run("HeapSort", func(b *testing.B) {
c := make([]int, len(a))
copy(c, a)
b.ResetTimer()
for i := 0; i < b.N; i++ {
HeapSort(c)
}
})
b.Run("BucketSort", func(b *testing.B) {
c := make([]int, len(a))
copy(c, a)
b.ResetTimer()
for i := 0; i < b.N; i++ {
BucketSort(c)
}
})
b.Run("FastSort", func(b *testing.B) {
c := make([]int, len(a))
copy(c, a)
b.ResetTimer()
for i := 0; i < b.N; i++ {
FastSort(c)
}
})
}
go test -v -bench=. -benchmem
=== RUN TestSort
sort_test.go:28: before sort: [313 439 911 211 177 638 25 932 584 340]
sort_test.go:29: expect: [25 177 211 313 340 439 584 638 911 932]
=== RUN TestSort/FastSort
=== RUN TestSort/ShellSort
=== RUN TestSort/MergeSort
=== RUN TestSort/SelectSort
=== RUN TestSort/BubbleSort
=== RUN TestSort/HeapSort
=== RUN TestSort/BucketSort
=== RUN TestSort/InsertSort
--- PASS: TestSort (0.00s)
--- PASS: TestSort/FastSort (0.00s)
--- PASS: TestSort/ShellSort (0.00s)
--- PASS: TestSort/MergeSort (0.00s)
--- PASS: TestSort/SelectSort (0.00s)
--- PASS: TestSort/BubbleSort (0.00s)
--- PASS: TestSort/HeapSort (0.00s)
--- PASS: TestSort/BucketSort (0.00s)
--- PASS: TestSort/InsertSort (0.00s)
goos: linux
goarch: amd64
pkg: coco/sort
cpu: Intel(R) Xeon(R) Gold 6133 CPU @ 2.50GHz
BenchmarkSort
BenchmarkSort/InsertSort
BenchmarkSort/InsertSort-8 40 27907640 ns/op 0 B/op 0 allocs/op
BenchmarkSort/ShellSort
BenchmarkSort/ShellSort-8 9962 109687 ns/op 0 B/op 0 allocs/op
BenchmarkSort/MergeSort
BenchmarkSort/MergeSort-8 1437 819987 ns/op 1112713 B/op 9999 allocs/op
BenchmarkSort/SelectSort
BenchmarkSort/SelectSort-8 16 67707251 ns/op 0 B/op 0 allocs/op
BenchmarkSort/BubbleSort
BenchmarkSort/BubbleSort-8 16 63796250 ns/op 0 B/op 0 allocs/op
BenchmarkSort/HeapSort
BenchmarkSort/HeapSort-8 1987 567119 ns/op 0 B/op 0 allocs/op
BenchmarkSort/BucketSort
BenchmarkSort/BucketSort-8 1996 589339 ns/op 206690 B/op 801 allocs/op
BenchmarkSort/FastSort
BenchmarkSort/FastSort-8 100 36424629 ns/op 0 B/op 0 allocs/op
PASS
ok coco/sort 13.064s