Golang数组或切片排序
引言
之前,刷leetcode时候,有些题是需要排序的,比如:
a := []int{2, 1, 3 ,4}
sort.Ints(a)
fmt.Println(a) // 1,2,3,4
结果:
[1 2 3 4]
探究源码
我们看一下sort.Ints()源代码:
// Ints sorts a slice of ints in increasing order.
func Ints(a []int) { Sort(IntSlice(a)) } // 按递增顺序对整型数组片进行排序。
问题来了,凭啥子就递增呢?那么我们看一下IntSlice()源码:
// IntSlice attaches the methods of Interface to []int, sorting in increasing order.
type IntSlice []int // IntSlice将Interface的方法附加到[]int上,并按递增顺序排序。
凭啥子递增呢?继续看:
func (p IntSlice) Len() int { return len(p) }
func (p IntSlice) Less(i, j int) bool { return p[i] < p[j] } // 在这, p[i] < p[j] // 递增, 如果p[i] > p[j] // 递减呗,看来要对[]int重写呀
func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
在这, p[i] < p[j] 递增, 如果p[i] > p[j] 递减呗,看来要对[]int附加的方法进行重写呀。
注意:sort.Sort(data Interface) , 传递的是接口,我们看一下源码
// Sort sorts data.
// It makes one call to data.Len to determine n, and O(n*log(n)) calls to // 快排
// data.Less and data.Swap. The sort is not guaranteed to be stable. // 重写less和swap,不过快排是不稳定排序
func Sort(data Interface) {
n := data.Len()
quickSort(data, 0, n, maxDepth(n))
}
例子:
type sortable []int // 给[]int 重写三个方法
func (p sortable) Len() int { return len(p) }
func (p sortable) Less(i, j int) bool { return p[i] > p[j] }
func (p sortable) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func main() {
a := []int{2, 1, 3, 4}
sort.Sort(sortable(a))
fmt.Println(a)
}
结果:
[4 3 2 1]
还有一种方法:sort.Slice,只需要写个less的fun即可,不信看源码:
// Slice sorts the provided slice given the provided less function. // 提供less func进行排序
//
// The sort is not guaranteed to be stable. For a stable sort, use // 如果想稳定,可以使用SliceStable
// SliceStable.
//
// The function panics if the provided interface is not a slice. // 必须是切片,要不然崩溃
func Slice(slice interface{}, less func(i, j int) bool) {
rv := reflectValueOf(slice) // 反射
swap := reflectSwapper(slice) // 反射
length := rv.Len() // 通过反射获取rv,swap,len, 所以只需要参数提供less fun 即可
quickSort_func(lessSwap{less, swap}, 0, length, maxDepth(length))
}
于是:
func main() {
a := []int{2, 1, 3, 4}
less := func(i, j int) bool {
return a[i] > a[j]
}
sort.Slice(a, less)
fmt.Println(a)
}
结果:
[4 3 2 1]
二维
其实和一维是差不多的,也是以上两个方法
sort.Sort(data Interface)sort.Slice(slice interface{}, less func(i, j int)
总结
简单排序的话,可以使用两种方法:
sort.Sort(data Interface)sort.Slice(slice interface{}, less func(i, j int)