golang基础-排序sort

本文深入讲解了使用Go语言进行各种排序的方法,包括基本类型如int、float64、string的排序,以及如何自定义排序规则对结构体进行排序。通过实例展示了如何实现结构体的直接排序和通过包装器实现灵活的排序逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单排序

基本类型 int、float64、string 的排序
[]int、[]float64、[]string排序



	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"}

	sort.Sort(sort.Reverse(sort.IntSlice(intListt)))
	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]
[9 8 7 6 5 4 3 2 1 0]
[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]

查询

我们还可以查询是否存在

ints := []int{5, 2, 6, 3, 1, 4,4}
	ipos := sort.SearchInts(ints, 43)
	fmt.Print(ipos,"\n")

	str:=[]string{"a","c","b"}
	sp:=sort.SearchStrings(str,"cdd")
	sp1:=sort.SearchStrings(str,"b")
	fmt.Print(sp,sp1)

结果输出

7
3 1

自定义排序

我们先看一个简单的自定义排序
通过看sort源码可以看到

type Interface interface {
	// Len is the number of elements in the collection.
	Len() int
	// Less reports whether the element with
	// index i should sort before the element with index j.
	Less(i, j int) bool
	// Swap swaps the elements with indexes i and j.
	Swap(i, j int)
}

下面到例子,我们可以为sort.Sort函数,提供一个实现了接口的struct

doubles := []float64{3.5, 4.2, 8.9, 100.98, 20.14, 79.32}
sort.Sort(Reverse{sort.Float64Slice(doubles)})    // float64 逆序排序
fmt.Print(doubles)
type Reverse struct {
	sort.Interface    // 这样, Reverse 可以接纳任何实现了 sort.Interface (包括 Len, Less, Swap 三个方法) 的对象
}
func (r Reverse) Less(i, j int) bool {
	return r.Interface.Less(j, i)
}

输出如下:

[100.98 79.32 20.14 8.9 4.2 3.5]

结构体类型的排序(一)


	people := [] Person{
		{"zhang san", 12},
		{"li si", 30},
		{"wang wu", 52},
		{"zhao liu", 26},
	}

	fmt.Println(people)

	sort.Sort(PersonSlice(people))    // 按照 Age 的逆序排序
	fmt.Println(people)

	sort.Sort(sort.Reverse(PersonSlice(people)))    // 按照 Age 的升序排序
	fmt.Println(people)

type PersonSlice [] Person

type Person struct {
	Name string    // 姓名
	Age  int    // 年纪
}


func (a PersonSlice) Len() int {    // 重写 Len() 方法
	return len(a)
}
func (a PersonSlice) Swap(i, j int){     // 重写 Swap() 方法
	a[i], a[j] = a[j], a[i]
}
func (a PersonSlice) Less(i, j int) bool {    // 重写 Less() 方法, 从大到小排序
	return a[j].Age < a[i].Age
}

代码输出如下:

[{zhang san 12} {li si 30} {wang wu 52} {zhao liu 26}]
[{wang wu 52} {li si 30} {zhao liu 26} {zhang san 12}]
[{zhang san 12} {zhao liu 26} {li si 30} {wang wu 52}]

结构体类型的排序(二)

方法 1 的缺点是 : 根据 Age 排序需要重新定义 PersonSlice 方法,绑定 Len 、 Less 和 Swap 方法, 如果需要根据 Name 排序, 又需要重新写三个函数; 如果结构体有 4 个字段,有四种类型的排序,那么就要写 3 × 4 = 12 个方法, 即使有一些完全是多余的, O__O"… 仔细思量一下,根据不同的标准 Age 或是 Name, 真正不同的体现在 Less 方法上,所以, me 们将 Less 抽象出来, 每种排序的 Less 让其变成动态的,比如下面一种方法。

people := [] Person{
		{"zhang san", 12},
		{"li si", 30},
		{"wang wu", 52},
		{"zhao liu", 26},
	}

	fmt.Println(people)

	sort.Sort(PersonWrapper{people, func(p, q *Person) bool {
		return q.Age < p.Age // Age 递减排序
	}})

	fmt.Println(people)
	sort.Sort(PersonWrapper{people, func(p, q *Person) bool {
		return p.Name < q.Name // Name 递增排序
	}})
	fmt.Println(people)

type Person struct {
	Name string // 姓名
	Age  int    // 年纪
}

type PersonWrapper struct {
	people [] Person
	by     func(p, q *Person) bool
}

func (pw PersonWrapper) Len() int { // 重写 Len() 方法
	return len(pw.people)
}
func (pw PersonWrapper) Swap(i, j int) { // 重写 Swap() 方法
	pw.people[i], pw.people[j] = pw.people[j], pw.people[i]
}
func (pw PersonWrapper) Less(i, j int) bool { // 重写 Less() 方法
	return pw.by(&pw.people[i], &pw.people[j])
}

输出如下:

[{zhang san 12} {li si 30} {wang wu 52} {zhao liu 26}]
[{wang wu 52} {li si 30} {zhao liu 26} {zhang san 12}]
[{li si 30} {wang wu 52} {zhang san 12} {zhao liu 26}]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值