Go中三种排序:排序整数、浮点数和字符串切片,使用自定义比较器排序,排序任意数据结构

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

sort:排序,提供了对切片和用户定义的集合进行排序

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

  • sort.Ints
  • sort.Floats
  • sort.Strings
package main

import (
	"fmt"
	"sort"
)

func main() {


	intList := [] int {2, 4, 3, 5, 7}
	float8List := [] float64 {4.2, 5.9, 12.3, 10.0}
	stringList := [] string {"a", "c", "b", "w", "y"}

	sort.Ints(intList)
	sort.Float64s(float8List)
	sort.Strings(stringList)

	fmt.Printf("%v\n%v\n%v\n", intList, float8List, stringList)


	intListt := [] int {2, 4, 3, 5, 7, 6, 9, 8, 1, 0}
	float8Listt := [] float64 {4.2, 5.9, 12.3, 10.0, 50.4, 99.9, 31.4, 27.81828, 3.14}
	stringListt := [] string {"a", "c", "b", "d", "f", "i", "z", "x", "w", "y"}
	//IntSlice将interface的方法附加到[]int上并按递增顺序排序
	s :=sort.IntSlice(intListt)
	sort.Sort(s)//递增
	fmt.Println("s",s)
	//Reverse:返回数据的反响顺序
	sort.Sort(sort.Reverse(sort.Float64Slice(float8Listt)))//递减
	sort.Sort(sort.Reverse(sort.StringSlice(stringListt)))

	fmt.Printf("%v\n%v\n%v\n", intListt, float8Listt, stringListt)


}

输出

[2 3 4 5 7]
[4.2 5.9 10 12.3]
[a b c w y]
s [0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4 5 6 7 8 9]
[99.9 50.4 31.4 27.81828 12.3 10 5.9 4.2 3.14]
[z y x w i f d c b a]

使用自定义比较器排序

  • 使用sort.Slice函数排序,它使用一个用户提供的函数来对序列进行排序,函数类型为func(i, j int) bool,其中参数i, j是序列中的索引。
  • sort.SliceStable在排序切片时会保留相等元素的原始顺序。
  • 上面两个函数让我们可以排序结构体切片(order by struct field value)。
family := []struct {
    Name string
    Age  int
}{
    {"Alice", 23},
    {"David", 2},
    {"Eve", 2},
    {"Bob", 25},
}
 
// 用 age 排序,年龄相等的元素保持原始顺序
sort.SliceStable(family, func(i, j int) bool {
    return family[i].Age < family[j].Age
})
fmt.Println(family) // [{David 2} {Eve 2} {Alice 23} {Bob 25}]

排序任意数据结构

  • 使用sort.Sort或者sort.Stable函数。
  • 他们可以排序实现了sort.Interface接口的任意类型

一个内置的排序算法需要知道三个东西:序列的长度,表示两个元素比较的结果,一种交换两个元素的方式;这就是sort.Interface的三个方法:

type Interface interface {
    Len() int
    Less(i, j int) bool // i, j 是元素的索引
    Swap(i, j int)
}

还是以上面结构体切片为例子,我们为切片类型自定义一个类型名,然后在自定义的类型上实现srot.Interfce接口

type Person struct {
    Name string
    Age  int
}
 
// ByAge 通过对age排序实现了sort.Interface接口
type ByAge []Person
 
func (a ByAge) Len() int           { return len(a) }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
 
func main() {
    family := []Person{
        {"David", 2},
        {"Alice", 23},
        {"Eve", 2},
        {"Bob", 25},
    }
    sort.Sort(ByAge(family))
    fmt.Println(family) // [{David, 2} {Eve 2} {Alice 23} {Bob 25}]
}

实现了sort.Interface的具体类型不一定是切片类型;下面的customSort是一个结构体类型。


package main

import (
"fmt"
"sort"
)


type Person struct {
	Name string
	Age int
}


//实现sort.Interface的具体类型不一定是切片类型;下面的customSort是一个结构体类型
type customSort struct {
	p    []Person
	less func(x, y Person) bool
}

func (x customSort) Len() int {return len(x.p)}
func (x customSort) Less(i, j int) bool { return x.less(x.p[i], x.p[j]) }
func (x customSort) Swap(i, j int)      { x.p[i], x.p[j] = x.p[j], x.p[i] }


func main() {
	family := []Person{
		{"David", 2},
		{"Alice", 23},
		{"Eve", 2},
		{"Bob", 25},
	}
	//func Sort(data Interface):对data进行排序。他调用一次data.Len来决定排序的长度 n。
	//调用data.Less和data.Swap的开销为O(n*log(n)), 此排序为不稳定排序。他根据不同形式决定使用不用的排序方式(插入排序,堆排序,快排)
	//定义一个根据多字段排序的函数,它主要的排序键是Age,Age 相同了再按 Name 进行倒序排序。
	//下面是该排序的调用,其中这个排序使用了匿名排序函数:
	sort.Sort(customSort{family, func(x, y Person) bool {
		if x.Age !=y.Age {
			return x.Age<y.Age
		}
		if x.Name !=x.Name {
			return x.Name>y.Name
		}
		return false
	}})
	fmt.Println(family)

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值