Golang数组或切片排序

3,508 阅读2分钟

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)

定期更新go-notes