Sort

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)
}