参考 排序算法
sort
对常用切片类型的排序
sort 包提供了对 []int 切片、[]float64 切片和 []string 切片完整支持,主要包括:
- 对基本数据类型切片的排序支持 ```go // Ints sorts a slice of ints in increasing order. func Ints(x []int) { Sort(IntSlice(x)) }
// Float64s sorts a slice of float64s in increasing order. // Not-a-number (NaN) values are ordered before other values. func Float64s(x []float64) { Sort(Float64Slice(x)) }
// Strings sorts a slice of strings in increasing order. func Strings(x []string) { Sort(StringSlice(x)) }
- 判断基本数据类型切片是否已经排好序```go// IntsAreSorted reports whether the slice x is sorted in increasing order.func IntsAreSorted(x []int) bool { return IsSorted(IntSlice(x)) }// Float64sAreSorted reports whether the slice x is sorted in increasing order,// with not-a-number (NaN) values before any other values.func Float64sAreSorted(x []float64) bool { return IsSorted(Float64Slice(x)) }// StringsAreSorted reports whether the slice x is sorted in increasing order.func StringsAreSorted(x []string) bool { return IsSorted(StringSlice(x)) }
对排好序的数据集合逆序,不必修改 Less() 方法的代码
sort.Sort(sort.Reverse(data))
对自定义数据类型的排序
需要实现
sort.Interface接口的三个方法,比较复杂的是Less(i, j int)方法,简言之就是位于索引 i 的元素是否应该排序在位于索引 j 的元素之前。// An implementation of Interface can be sorted by the routines in this package.// The methods refer to elements of the underlying collection by integer index.type Interface interface {// Len is the number of elements in the collection.Len() int// Less reports whether the element with index i// must sort before the element with index j.//// If both Less(i, j) and Less(j, i) are false,// then the elements at index i and j are considered equal.// Sort may place equal elements in any order in the final result,// while Stable preserves the original input order of equal elements.//// Less must describe a transitive ordering:// - if both Less(i, j) and Less(j, k) are true, then Less(i, k) must be true as well.// - if both Less(i, j) and Less(j, k) are false, then Less(i, k) must be false as well.//// Note that floating-point comparison (the < operator on float32 or float64 values)// is not a transitive ordering when not-a-number (NaN) values are involved.// See Float64Slice.Less for a correct implementation for floating-point values.Less(i, j int) bool// Swap swaps the elements with indexes i and j.Swap(i, j int)}
实现上述接口后,可以直接调用函数进行排序
sort.Sort(data)
试想,对于自定义结构体数组,我们如果想进行排序,还需要额外封装一层结构体,十分繁琐。sort 包提供了相关方法,我们提供比较函数即可
func Slice(slice interface{}, less func(i, j int) bool)func SliceStable(slice interface{}, less func(i, j int) bool)func SliceIsSorted(slice interface{}, less func(i, j int) bool) bool
举个例子,完成一个自定义结构体 slice 的排序
people := []struct {Name stringAge int}{{"Gopher", 7},{"Alice", 55},{"Vera", 24},{"Bob", 75},}sort.Slice(people, func(i, j int) bool { return people[i].Age < people[j].Age }) // 按年龄升序排序fmt.Println("Sort by age:", people)
search
sort 包还提供了对基本数据元素查找 的功能,注意输入必须是已经排序过的;输出是被查找元素 x 的位置(如果 x 存在),或者 x 应该被插入的位置(如果 x 不存在)
// SearchInts searches for x in a sorted slice of ints and returns the index// as specified by Search. The return value is the index to insert x if x is// not present (it could be len(a)).// The slice must be sorted in ascending order.//func SearchInts(a []int, x int) int {return Search(len(a), func(i int) bool { return a[i] >= x })}func SearchFloat64s(a []float64, x float64) intfunc SearchStrings(a []string, x string) int
同样,对于自定义结构体的列表查询,也需要实现一个 func(int) bool 函数,此函数的实现应该使得对于被查找的元素 x 之前所有值的返回值为 false
举个例子
a := []int{2, 3, 4, 200, 100, 21, 234, 56}x := 21sort.Slice(a, func(i, j int) bool { return a[i] < a[j] }) // 升序排序index := sort.Search(len(a), func(i int) bool { return a[i] >= x }) // 查找元素if index < len(a) && a[index] == x {fmt.Printf("found %d at index %d in %v\n", x, index, a)} else {fmt.Printf("%d not found in %v,index:%d\n", x, a, index)}
