go实现十大经典排序
排序代码:
package sort
import (
"math"
"math/rand"
"strconv"
"time"
)
func NewNums(length int, maxNum int) []int {
nums := make([]int, length)
rand.Seed(time.Now().UnixNano())
for i := 0; i < length; i++ {
nums[i] = rand.Intn(maxNum)
}
return nums
}
func BubbleSort(nums []int) []int {
if len(nums) < 2 {
return nums
}
for i:=0;i<len(nums);i++ {
for j:=1;j<len(nums)-i;j++ {
if nums[j-1] > nums[j] {
nums[j-1], nums[j] = nums[j], nums[j-1]
}
}
}
return nums
}
func SelectSort(nums []int) []int {
if len(nums) < 2 {
return nums
}
for i:=0;i<len(nums);i++ {
for j:=i+1;j<len(nums);j++ {
if nums[i] > nums[j] {
nums[i], nums[j] = nums[j], nums[i]
}
}
}
return nums
}
func InsertSort(nums []int) []int {
if len(nums) < 2 {
return nums
}
for i:=1;i<len(nums);i++ {
tmp := nums[i]
j := i-1
for j>=0 && nums[j] > tmp {
nums[j+1] = nums[j]
j--
}
nums[j+1] = tmp
}
return nums
}
func HellSort(nums []int) []int {
if len(nums) < 2 {
return nums
}
for step:=len(nums)/2; step>0; step=step/2 {
for i:=step; i<len(nums); i++ {
for j:=i; j-step >=0 && nums[j-step] > nums[j]; j=j-step {
nums[j-step], nums[j] = nums[j], nums[j-step]
}
}
}
return nums
}
func MergeSort(nums []int) []int {
if len(nums) < 2 {
return nums
}
merge := func(left []int, right []int) []int {
res := make([]int, len(left)+len(right))
var lIndex, rIndex, index int
for lIndex < len(left) && rIndex < len(right) {
if left[lIndex] < right[rIndex] {
res[index] = left[lIndex]
lIndex++
} else {
res[index] = right[rIndex]
rIndex++
}
index++
}
copy(res[index:], left[lIndex:])
copy(res[index+len(left)-lIndex:], right[rIndex:])
return res
}
var sort func(nums []int) []int
sort = func(nums []int) []int {
if len(nums) <= 1 {
return nums
}
mid := len(nums)/2
left := sort(nums[:mid])
right := sort(nums[mid:])
return merge(left, right)
}
return sort(nums)
}
func MergeSortII(nums []int) []int {
if len(nums) < 2 {
return nums
}
merge := func(left []int, right []int) []int {
res := make([]int, len(left)+len(right))
var lIndex, rIndex, index int
for lIndex < len(left) && rIndex < len(right) {
if left[lIndex] < right[rIndex] {
res[index] = left[lIndex]
lIndex++
} else {
res[index] = right[rIndex]
rIndex++
}
index++
}
copy(res[index:], left[lIndex:])
copy(res[index+len(left)-lIndex:], right[rIndex:])
return res
}
var sort_iter func(nums []int) []int
sort_iter = func(nums []int) []int {
i := 1 //子序列大小初始1
res := make([]int, 0)
// i控制每次划分的序列长度
for i < len(nums) {
// j根据i值执行具体的合并
j := 0
// 按顺序两两合并,j用来定位起始点
// 随着序列翻倍,每次两两合并的数组大小也翻倍
for j < len(nums) {
if j+2*i > len(nums) {
res = merge(nums[j:j+i], nums[j+i:])
} else {
res = merge(nums[j:j+i], nums[j+i:j+2*i])
}
// 通过index控制每次将合并的数据填入nums中
// 重填入的次数和合并及二叉树的高度相关
index := j
for _, v := range res {
nums[index] = v
index++
}
j = j + 2*i
}
i *= 2
}
return nums
}
return sort_iter(nums)
}
func QuickSort(nums []int) []int {
if len(nums) < 2 {
return nums
}
var quick func(left int, right int) []int
quick = func(left int, right int) []int {
if left > right {
return nil
}
i, j, pivot := left, right, nums[left]
for i < j {
for i<j && nums[j] >= pivot {
j--
}
for i<j && nums[i] <= pivot {
i++
}
nums[i], nums[j] = nums[j], nums[i]
}
nums[i], nums[left] = nums[left], nums[i]
quick(left, i-1)
quick(i+1, right)
return nums
}
return quick(0, len(nums)-1)
}
func HeapSort(nums []int) []int {
if len(nums) < 2 {
return nums
}
// large heap
heapify := func(nums []int, root int, end int) {
for {
child := root*2 + 1
if child > end {
return
}
if child < end && nums[child] <= nums[child+1] {
child++
}
if nums[root] > nums[child] {
return
}
nums[root], nums[child] = nums[child], nums[root]
root = child
}
}
end := len(nums)-1
for i:=end/2;i>=0;i-- {
heapify(nums, i, end)
}
for i:=end;i>0;i-- {
nums[0], nums[i] = nums[i], nums[0]
end--
heapify(nums, 0, end)
}
return nums
}
func SmallHeapSort(nums []int) []int {
if len(nums) < 2 {
return nums
}
// min heap
heapify := func(nums []int, root int, end int) {
for {
child := root*2 + 1
if child > end {
return
}
if child < end && nums[child] >= nums[child+1] {
child++
}
if nums[root] < nums[child] {
return
}
nums[root], nums[child] = nums[child], nums[root]
root = child
}
}
end := len(nums)-1
for i:=end/2;i>=0;i-- {
heapify(nums, i, end)
}
for i:=end;i>=0;i-- {
nums[0], nums[i] = nums[i], nums[0]
end--
heapify(nums, 0, end)
}
return nums
}
func TopKHeap(nums []int, k int) []int {
if len(nums) < 2 {
return nums
}
heapify := func(nums []int, root int, end int) {
for {
child := root*2 + 1
if child > end {
return
}
if child < end && nums[child] >= nums[child+1] {
child++
}
if nums[root] < nums[child] {
return
}
nums[root], nums[child] = nums[child], nums[root]
root = child
}
}
heap := nums[:k]
end := len(nums)-1
for i:=k/2;i>=0;i-- {
heapify(heap, i, k-1)
}
for i:=k;i<=end;i++ {
if nums[i] > heap[0] {
heap[0] = nums[i]
heapify(heap, 0, k-1)
}
}
for i:=k-1;i>=0;i-- {
heap[0], heap[i] = heap[i], heap[0]
k--
heapify(heap, 0, k)
}
return heap
}
func CountSort(nums []int) []int {
if len(nums) < 2 {
return nums
}
findMinMax := func(nums []int) (int, int) {
min, max := nums[0], nums[0]
for i:=0;i<len(nums);i++ {
if nums[i] > max {
max = nums[i]
}
if nums[i] < min {
min = nums[i]
}
}
return min, max
}
min, max := findMinMax(nums)
tmpNums := make([]int, max-min+1)
for i:=0;i<len(nums);i++ {
tmpNums[nums[i]-min]++
}
j := 0
for i:=0;i<len(nums);i++ {
for tmpNums[j] == 0 {
j++
}
nums[i] = j+min
tmpNums[j]--
}
return nums
}
func RadixSort(nums []int) []int {
if len(nums) < 2 {
return nums
}
max := nums[0]
for i:=0;i<len(nums);i++ {
if nums[i] > max {
max = nums[i]
}
}
for i:=0;i<len(strconv.Itoa(max));i++ {
buckets := make([][]int, 10)
for j:=0;j<len(nums);j++ {
n := nums[j] / int(math.Pow10(i)) % 10
buckets[n] = append(buckets[n], nums[j])
}
m := 0
for k:=0;k<len(buckets);k++ {
for p:=0;p<len(buckets[k]);p++ {
nums[m] = buckets[k][p]
m++
}
}
}
return nums
}
func BucketSort(nums []int) []int {
if len(nums) < 2 {return nums}
min, max := nums[0], nums[0]
for i:=0;i<len(nums);i++ {
if nums[i] > max {
max = nums[i]
}
if nums[i] < min {
min = nums[i]
}
}
bucketSize := 5
bucketCap := (max-min)/bucketSize + 1
buckets := make([][]int, bucketCap)
for i:=0;i<bucketCap;i++ {
buckets[i] = make([]int, 0)
}
for i:=0;i<len(nums);i++ {
n := (nums[i]-min) / bucketSize
buckets[n] = append(buckets[n], nums[i])
}
index := 0
for _, bucket := range buckets {
// sort in single bucket
bucket = func(nums []int) []int {
for i:=0;i<len(nums);i++ {
tmp := nums[i]
j := i-1
for j>=0 && nums[j] > tmp {
nums[j+1] = nums[j]
j--
}
nums[j+1] = tmp
}
return nums
}(bucket)
for _, num := range bucket {
nums[index] = num
index++
}
}
return nums
}
单元测试代码:
package sort
import (
"log"
"sort"
"testing"
)
func TestBubbleSort(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Ints(nums)
log.Printf("system sorted nums: %v\n", nums)
numsCp = BubbleSort(numsCp)
log.Printf("Bubble sorted nums: %v\n", numsCp)
for i:=0;i<len(nums);i++ {
if nums[i] != numsCp[i] {
t.Fatal("Bubble sort is not right!")
}
}
log.Println("Bubble sort passed.")
}
func TestSelectSort(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Ints(nums)
log.Printf("system sorted nums: %v\n", nums)
numsCp = SelectSort(numsCp)
log.Printf("Select sorted nums: %v\n", numsCp)
for i:=0;i<len(nums);i++ {
if nums[i] != numsCp[i] {
t.Fatal("Select sort is not right!")
}
}
log.Println("Select sort passed.")
}
func TestInsertSort(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Ints(nums)
log.Printf("system sorted nums: %v\n", nums)
numsCp = InsertSort(numsCp)
log.Printf("Insert sorted nums: %v\n", numsCp)
for i:=0;i<len(nums);i++ {
if nums[i] != numsCp[i] {
t.Fatal("Insert sort is not right!")
}
}
log.Println("Insert sort passed.")
}
func TestHellSort(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Ints(nums)
log.Printf("system sorted nums: %v\n", nums)
numsCp = HellSort(numsCp)
log.Printf("Hell sorted nums: %v\n", numsCp)
for i:=0;i<len(nums);i++ {
if nums[i] != numsCp[i] {
t.Fatal("Hell sort is not right!")
}
}
log.Println("Hell sort passed.")
}
func TestMergeSort(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Ints(nums)
log.Printf("system sorted nums: %v\n", nums)
numsCp = MergeSort(numsCp)
log.Printf("Merge sorted nums: %v\n", numsCp)
for i:=0;i<len(nums);i++ {
if nums[i] != numsCp[i] {
t.Fatal("Merge sort is not right!")
}
}
log.Println("Merge sort passed.")
}
func TestMergeSortII(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Ints(nums)
log.Printf("system sorted nums: %v\n", nums)
numsCp = MergeSortII(numsCp)
log.Printf("MergeII sorted nums: %v\n", numsCp)
for i:=0;i<len(nums);i++ {
if nums[i] != numsCp[i] {
t.Fatal("MergeII sort is not right!")
}
}
log.Println("MergeII sort passed.")
}
func TestQuickSort(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Ints(nums)
log.Printf("system sorted nums: %v\n", nums)
numsCp = QuickSort(numsCp)
log.Printf("Quick sorted nums: %v\n", numsCp)
for i:=0;i<len(nums);i++ {
if nums[i] != numsCp[i] {
t.Fatal("Quick sort is not right!")
}
}
log.Println("Quick sort passed.")
}
func TestHeapSort(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Ints(nums)
log.Printf("system sorted nums: %v\n", nums)
numsCp = HeapSort(numsCp)
log.Printf("Heap sorted nums: %v\n", numsCp)
for i:=0;i<len(nums);i++ {
if nums[i] != numsCp[i] {
t.Fatal("Heap sort is not right!")
}
}
log.Println("Heap sort passed.")
}
func TestSmallHeapSort(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Slice(nums, func(i, j int) bool {
return nums[i] > nums[j]
})
log.Printf("system sorted nums: %v\n", nums)
numsCp = SmallHeapSort(numsCp)
log.Printf("Heap sorted nums: %v\n", numsCp)
for i:=0;i<len(nums);i++ {
if nums[i] != numsCp[i] {
t.Fatal("Heap sort is not right!")
}
}
log.Println("Heap sort passed.")
}
func TestTopKHeap(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Slice(nums, func(i, j int) bool {
return nums[i] > nums[j]
})
log.Printf("system sorted nums: %v\n", nums)
numsCp = TopKHeap(numsCp, 10)
log.Printf("TopHeap sorted nums: %v\n", numsCp)
}
func TestCountSort(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Slice(nums, func(i, j int) bool {
return nums[i] < nums[j]
})
log.Printf("system sorted nums: %v\n", nums)
numsCp = CountSort(numsCp)
log.Printf("Count sorted nums: %v\n", numsCp)
for i:=0;i<len(nums);i++ {
if nums[i] != numsCp[i] {
t.Fatal("Count sort is not right!")
}
}
log.Println("Count sort passed.")
}
func TestRadixSort(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Slice(nums, func(i, j int) bool {
return nums[i] < nums[j]
})
log.Printf("system sorted nums: %v\n", nums)
numsCp = RadixSort(numsCp)
log.Printf("Radix sorted nums: %v\n", numsCp)
for i:=0;i<len(nums);i++ {
if nums[i] != numsCp[i] {
t.Fatal("Radix sort is not right!")
}
}
log.Println("Radix sort passed.")
}
func TestBucketSort(t *testing.T) {
nums := NewNums(10, 100)
log.Printf("origin nums: %v\n", nums)
numsCp := make([]int, len(nums))
copy(numsCp, nums)
sort.Slice(nums, func(i, j int) bool {
return nums[i] < nums[j]
})
log.Printf("system sorted nums: %v\n", nums)
numsCp = BucketSort(numsCp)
log.Printf("Bucket sorted nums: %v\n", numsCp)
for i:=0;i<len(nums);i++ {
if nums[i] != numsCp[i] {
t.Fatal("Bucket sort is not right!")
}
}
log.Println("Bucket sort passed.")
}