gofound/tests/sort_test.go

301 lines
5.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package tests
import (
"fmt"
"math/rand"
"sort"
"testing"
"myschools.me/suguo/gofound/searcher/utils"
)
//排序测试
// 冒泡排序测试
func TestSort(t *testing.T) {
//测试数据
var data []int
for i := 0; i < 100000; i++ {
//随机数
data = append(data, rand.Intn(100))
}
//fmt.Println("原始:", data)
//排序
data1 := data
var data2 = make([]int, len(data))
copy(data2, data)
var data3 = make([]int, len(data))
copy(data3, data)
var data4 = make([]int, len(data))
copy(data4, data)
_time := utils.ExecTime(func() {
BubbleSort(data1)
})
fmt.Println("冒泡排序耗时:", _time)
//fmt.Println("data1", data1)
//快速排序
_time = utils.ExecTime(func() {
//QuickSortAsc(data2, 0, len(data2)-1)
utils.QuickSortAsc(data2, 0, len(data2)-1, func(i int, j int) {
//log.Println(i, j)
})
})
fmt.Println("快速排序耗时:", _time)
//fmt.Println("data2", data2)
_time = utils.ExecTime(func() {
SelectSort(data3)
})
fmt.Println("选择排序耗时:", _time)
//fmt.Println("data3", data3)
_time = utils.ExecTime(func() {
InsertSort(data4)
})
fmt.Println("插入排序耗时:", _time)
}
// 冒泡排序
func BubbleSort(data []int) {
//排序
for i := 0; i < len(data)-1; i++ {
for j := 0; j < len(data)-1-i; j++ {
if data[j] > data[j+1] {
data[j], data[j+1] = data[j+1], data[j]
}
}
}
}
func SelectSort(arr []int) {
for j := 0; j < len(arr)-1; j++ {
max := arr[j]
maxIndex := j
for i := j + 1; i < len(arr); i++ {
if max < arr[i] {
//记录
max = arr[i]
maxIndex = i
}
}
//交换
if maxIndex != j {
arr[j], arr[maxIndex] = arr[maxIndex], arr[j]
}
//fmt.Printf("数据第 %v 次交换后为:\t%v\n", j+1, arr)
}
}
// 快速排序
func QuickSort(arr []int, start, end int) {
if start < end {
i, j := start, end
key := arr[(start+end)/2]
for i <= j {
for arr[i] < key {
i++
}
for arr[j] > key {
j--
}
if i <= j {
arr[i], arr[j] = arr[j], arr[i]
i++
j--
}
}
if start < j {
QuickSort(arr, start, j)
}
if end > i {
QuickSort(arr, i, end)
}
}
}
func InsertSort(list []int) {
n := len(list)
// 进行 N-1 轮迭代
for i := 1; i <= n-1; i++ {
deal := list[i] // 待排序的数
j := i - 1 // 待排序的数左边的第一个数的位置
// 如果第一次比较,比左边的已排好序的第一个数小,那么进入处理
if deal < list[j] {
// 一直往左边找,比待排序大的数都往后挪,腾空位给待排序插入
for ; j >= 0 && deal < list[j]; j-- {
list[j+1] = list[j] // 某数后移,给待排序留空位
}
list[j+1] = deal // 结束了,待排序的数插入空位
}
}
}
func TestFastSort(t *testing.T) {
//QuickSortDesc
//测试数据
var data []int
for i := 0; i < 1000; i++ {
//随机数
data = append(data, rand.Intn(100))
}
_time := utils.ExecTime(func() {
//utils.QuickSortDesc(data, 0, len(data)-1, func(i int, j int) {
//})
//sort.Ints(data)
sort.Sort(sort.Reverse(sort.IntSlice(data)))
//sort.Reverse(data)
})
fmt.Println("时间", _time)
fmt.Println(data)
}
// 获取数组最大值
func getMaxInArr(arr []int) int {
max := arr[0]
for i := 1; i < len(arr); i++ {
if arr[i] > max {
max = arr[i]
}
}
return max
}
func sortInBucket(bucket []int) { //此处实现插入排序方式,其实可以用任意其他排序方式
length := len(bucket)
if length == 1 {
return
}
for i := 1; i < length; i++ {
backup := bucket[i]
j := i - 1
//将选出的被排数比较后插入左边有序区
for j >= 0 && backup < bucket[j] { //注意j >= 0必须在前边否则会数组越界
bucket[j+1] = bucket[j] //移动有序数组
j-- //反向移动下标
}
bucket[j+1] = backup //插队插入移动后的空位
}
}
// 桶排序
func BucketSort(arr []int) []int {
//桶数
num := len(arr)
//k数组最大值
max := getMaxInArr(arr)
//二维切片
buckets := make([][]int, num)
//分配入桶
index := 0
for i := 0; i < num; i++ {
index = arr[i] * (num - 1) / max //分配桶index = value * (n-1) /k
buckets[index] = append(buckets[index], arr[i])
}
//桶内排序
tmpPos := 0
for i := 0; i < num; i++ {
bucketLen := len(buckets[i])
if bucketLen > 0 {
sortInBucket(buckets[i])
copy(arr[tmpPos:], buckets[i])
tmpPos += bucketLen
}
}
return arr
}
func TestFind(t *testing.T) {
data := make([]int, 0)
data2 := make([]int, 0)
for i := 0; i < 100000; i++ {
val := rand.Intn(100000)
data = append(data, val)
data2 = append(data2, val)
}
t1 := utils.ExecTime(func() {
sort.Sort(sort.IntSlice(data))
})
fmt.Println("快排用时", t1)
//fmt.Println(find(data, 1))
t2 := utils.ExecTime(func() {
BucketSort(data2)
for i, j := 0, len(data2)-1; i < j; i, j = i+1, j-1 {
data2[i], data2[j] = data2[j], data2[i]
}
})
fmt.Println("捅排", t2)
//fmt.Println("捅排", sort.Reverse(sort.IntSlice(data2)))
//查找优化,桶排序+map去重
}
func find(data []uint32, target uint32) (bool, int) {
low := 0
high := len(data) - 1
for low <= high {
mid := (low + high) / 2
if data[mid] == target {
return true, mid
} else if data[mid] < target {
high = mid - 1
} else {
low = mid + 1
}
}
return false, -1
}
func TestMerge(t *testing.T) {
data1 := make([]uint32, 0)
data2 := make([]uint32, 0)
for i := 0; i < 10000; i++ {
v := rand.Intn(10)
data1 = append(data1, uint32(v))
data2 = append(data2, uint32(v))
}
t1 := utils.ExecTime(func() {
temp := make([]uint32, 0)
for _, v := range data1 {
if found, _ := find(temp, v); found {
temp = append(temp, v)
}
}
fmt.Println(temp)
})
fmt.Println("二分法去重", t1)
t2 := utils.ExecTime(func() {
temp := make(map[uint32]bool, len(data2))
d := make([]uint32, 0)
for _, val := range data2 {
if _, ok := temp[val]; !ok {
temp[val] = true
d = append(d, val)
}
}
fmt.Println(d)
})
fmt.Println("map去重", t2)
}