go源码阅读sort包3种类型排序

海生上海市浦东新区环科路

一、介绍

go doc sort.sort 包,查看包主要功能函数
输出:

type Interface interface {
    Len() int
    Less(i, j int) bool
    Swap(i, j int)
}
func Sort(data Interface)

只有一个Sort函数,参数为实现了len(),less(),swap(),三个方法的Interface 接口。

二、排序整数、浮点数和字符串切片

对于 []int, []float, []string 这种元素类型是基础类型的切片使用 sort 包提供的下面几个函数进行排序。

sort.Ints
sort.Float64s
sort.Strings

使用示例如下:

func TestSort(t *testing.T) {
    //sort.Ints 对 []int 类型进行排序
    i := []int{4, 2, 3, 1}
    sort.Ints(i)
    fmt.Println(i) // [1 2 3 4]

    //sort.Float64s 对 []float64 类型进行排序
    f := []float64{4.2, 2.3, 3.1, 1.2}
    sort.Float64s(f)
    fmt.Println(f) // [1.2 2.3 3.1 4.2]

    //sort.Strings 对 []string 类型进行排序
    s := []string{"b", "d", "c", "a"}
    sort.Strings(s)
    fmt.Println(s) //[a b c d]
}

三、整数排序 sort.Ints()源码阅读

先手我们找到 sort.Ints()函数

// Ints sorts a slice of ints in increasing order.
func Ints(x []int) { Sort(IntSlice(x)) }

参数为 []int,调用了 Sort(IntSlice(x)),我们再看一下sort.Sort()函数

func Sort(data Interface) {
    n := data.Len()
    quickSort(data, 0, n, maxDepth(n))
}
  • 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.

参数为 IntSlice接口的x
我们再看下sort.IntSlice,实现了len(),less(),swap(),三个方法的Interface 接口

type IntSlice []int

func (x IntSlice) Len() int           { return len(x) }
func (x IntSlice) Less(i, j int) bool { return x[i] < x[j] }
func (x IntSlice) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }

四、自己实现[]uint类型的slice 排序

通过上面我们发现只要实现一个实现了len(),less(),swap(),三个方法的Interface 接口,就可以掉用sort.Sort(Interface)这个方法,那么我们自己实现一下,代码如下:


type UintSlice []uint

func (x UintSlice) Len() int           { return len(x) }
func (x UintSlice) Less(i, j int) bool { return x[i] < x[j] }
func (x UintSlice) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }

func TestSortUint(t *testing.T) {
    u := []uint{4, 2, 1, 3}
    sort.Sort(UintSlice(u))
    fmt.Println(u) //[1 2 3 4]
}

我们申明了一个UintSlice结构体,然后实现len(),less(),swap(),三个方法的Interface 接口,最后再调用sort.Sort(UintSlice(u)),就可以排序了。

五、对于结构体,sort.slice()的排序

可以参考sort.slice

func Slice(slice interface{}, less func(i, j int) bool)

使用:

type PersonAge struct {
    Name string
    Age  int
}
func TestSlice(t *testing.T) {
    //按age 升序
    ps := []PersonAge{
        {"bo", 31},
        {"ao", 42},
        {"ao", 41},
        {"ao", 40},
        {"ao", 45},
        {"co", 17},
        {"do", 26},
    }
    sort.Slice(ps, func(i, j int) bool {
        return ps[i].Age < ps[j].Age
    })
    t.Log(ps)
}

输出:

[{co 17} {do 26} {bo 31} {ao 40} {ao 41} {ao 42} {ao 45}]

六、对于结构体,sort.Sort()的排序

type PersonAge struct {
    Name string
    Age  int
}
type PersonAgeArr []PersonAge

func (p PersonAgeArr) Len() int      { return len(p) }
func (p PersonAgeArr) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p PersonAgeArr) Less(i, j int) bool {
    if p[i].Age < p[j].Age {
        return true
    }
    return false
}

func TestSort4(t *testing.T) {
    ps := []PersonAge{
        {"bo", 31},
        {"ao", 42},
        {"ao", 41},
        {"ao", 40},
        {"ao", 45},
        {"co", 17},
        {"do", 26},
    }
    sort.Sort(PersonAgeArr(ps))
    t.Log(ps)
}

输出:

[{co 17} {do 26} {bo 31} {ao 40} {ao 41} {ao 42} {ao 45}]
阅读 225

go语言源码阅读
go语言源码阅读

与黑夜里,追求那一抹萤火。

33 声望
5 粉丝
0 条评论

与黑夜里,追求那一抹萤火。

33 声望
5 粉丝
文章目录
宣传栏