sort —— 排序算法 #
sort包提供了对[]int切片、[]float64切片和[]string切片完整支持,主要包括:
- 对基本数据类型切片的排序支持
- 基本数据元素查找
- 判断基本数据类型切片是否已经排好序
- 对排好序的数据集合逆序
对[]int切片排序是更常使用sort.Ints(),而不是直接使用IntSlice类型。
s := []int{5, 2, 6, 3, 1, 4} // 未排序的切片数据
sort.Ints(s)
fmt.Println(s) //将会输出[1 2 3 4 5 6]
如果要使用降序排序,显然要用前面提到的Reverse()方法:
s := []int{5, 2, 6, 3, 1, 4} // 未排序的切片数据
sort.Sort(sort.Reverse(sort.IntSlice(s)))
fmt.Println(s) //将会输出[6 5 4 3 2 1]
如果要查找整数x在切片a中的位置,相对于前面提到的Search()方法,sort包提供了SearchInts():
func SearchInts(a []int, x int) int
注意,SearchInts()的使用条件为:切片a已经升序排序
s := []int{5, 2, 6, 3, 1, 4} // 未排序的切片数据
sort.Ints(s) //排序后的s为[1 2 3 4 5 6]
fmt.Println(sort.SearchInts(s, 3)) //将会输出2
// []int 排序
slInt := []int{5, 2, 6, 3, 1, 4} // unsorted
sort.Ints(slInt)
fmt.Println(slInt) // 输出 [1 2 3 4 5 6]
// []float64 排序
slF64 := []float64{5.2, -1.3, 0.7, -3.8, 2.6} // unsorted
sort.Float64s(slF64)
fmt.Println(slF64) // 输出 [-3.8 -1.3 0.7 2.6 5.2]
// []string 字典序
slStr := []string{"Go", "Bravo", "Gopher", "Alpha", "Grin", "Delta"}
sort.Strings(slStr)
fmt.Println(slStr) // 输出 [Alpha Bravo Delta Go Gopher Grin]
sort.Search #
该函数使用二分查找的方法,会从[0, n)中取出一个值index,index为[0, n)中最小的使函数f(index)为True的值,并且f(index+1)也为True。 如果无法找到该index值,则该方法为返回n
index := sort.Search(n int,f func(i int) bool) int
func main() {
a := []int{1,2,3,4,5}
d := sort.Search(len(a), func(i int) bool { return a[i]>=3})
fmt.Println(d)
}
执行结果:2
sort.SearchInts #
func SearchInts(a []int, x int) int
SearchInts 在已排序的整数切片中搜索 x 并返回 Search 指定的索引。如果 x 不存在,则返回值是插入 x 的索引(它可能是 len(a))。切片必须按升序排序。
func main() {
a := []int{1, 2, 3, 4, 6, 7, 8}
x := 2
i := sort.SearchInts(a, x)
fmt.Printf(i)
}
输出:1
sort.Slice #
sort.Slice
是go 1.8版本引入的一个强大排序函数。第一个参数是待排序的任意类型slice
;第二个参数是less function
,用于比较 i 和 j 对应的元素大小,“较小"的排在前面。注意这里并不真的按照"大小"排序,而是根据less func
的定义来决定排序。
func Slice(x any, less func(i, j int) bool)
func Slice(x interface{}, less func(i, j int) bool)
// 第一个形参是:待排序数据
x interface{}
// 第二个形参是:排序判断方法
// 形参i 代表后一个元素
// 形参j 代表前一元素
// 返回值:代表i,j是否交换。true:交换,false:不交换。
less func(i, j int) bool
func main() {
people := []struct {
Name string
Age int
}{
{"Gopher", 7},
{"Alice", 55},
{"Vera", 24},
{"Bob", 75},
}
sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name })
fmt.Println("By name:", people)
sort.Slice(people, func(i, j int) bool { return people[i].Age < people[j].Age })
fmt.Println("By age:", people)
}