Go语言排序

Go语言排序,第1张

对于Go语言来说,主要对两种类型的数据进行排序(一般都是对于切片类型数据排序):① 切片 ② 结构体,切片一般对应基本的数据类型,例如int,float类型的数字,string字符串等基本数据类型的切片;对于结构体的排序,类似于python列表嵌套元组(或者是列表嵌套列表),例如对于python中的列表a:a = [(1,2,4),(3,4,2),(5,2,7)],python对列表中的元组排序可以使用python中的sort方法并且利用lambda表达式自定义按照元组的第几个元素进行排序:a.sort(key=lambda x: x[1]),而Go语言的结构体排序类似于python列表嵌套元组然后进行排序,Go语言中一般使用切片来嵌套结构体进行排序,嵌套结构体之后就可以实现比较复杂的数据结构的排序,下面是一些常见排序方法:

1. 对int类型的切片从小到大排序可以使用sort.Ints函数,这个函数默认是从小到大进行排序,如果需要从大到小排序第一种方法可以使用sort.Sort(sort.Reverse(sort.IntSlice(slice)))进行排序,其中slice为切片;第二种方法调用sort.Sort()函数,需要实现Sort接口中的Len(),Less(),Swap()方法,其中排序的核心是Less函数,需要在Less函数中定义排序的规则也按照什么来排序;第三种方法可以使用sort.Slice()函数进行排序,此时需要传递一个匿名函数,这个函数需要实现类似于Sort接口中的Less函数的功能,主要是定义排序的规则,而对于浮点数排序可以使用Float64s函数:

package main

import (
	"fmt"
	"sort"
)

type hp []int

// 下面三个方法属于Sort接口中的方法, 任何实现了Sort接口中的方法都可以自定义排序
func (p hp) Len() int { return len(p) }

// 核心是Less方法, 定义比较规则
func (p hp) Less(i, j int) bool { return p[i] > p[j] }

func (p hp) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

func main() {
	a := []int{1, 4, 23, 5, 6, 19, 34}
	// 1. 利用Ints函数对int类型的整数从小到大进行排序
	fmt.Println("Ints函数对int类型切片升序排序: ")
	sort.Ints(a)
	fmt.Println(a)

	// 2. 从大到小排序
	fmt.Println("从大到小排序: ")
	b := []int{10, 2, 5, 12, 4, 35}
	// Sort函数的参数为一个interface接口, sort.Reverse函数返回的就是一个接口
	sort.Sort(sort.Reverse(sort.IntSlice(b)))
	fmt.Println(b)

	// 3. 使用sort.Sort()函数对切片进行排序, 函数的参数为接口类型(可以参照官方文档中的例子进行修改)
	c := []int{1, 4, 2, 5, 8}
	// 实现Sort接口中的三个方法进行排序
	fmt.Println("实现Sort接口中的三个方法进行排序")
	sort.Sort(hp(c))
	fmt.Println(c)

	// 4. 使用Slice函数对切片进行排序, 第一个参数为待排序的切片类型, 并且传递一个匿名函数实现Sort接口中Less函数的相同要求
	d := []int{1, 6, 3, 4, 19, 34, 5}
	sort.Slice(d, func(i, j int) bool {
		// 自定义排序的规则, 大于表示从大到小进行排序
		return d[i] > d[j]
	})
	fmt.Print(d)
}

2. 对string字符串类型的切片进行排序,与int类型的切片排序是类似的:

package main

import (
	"fmt"
	"sort"
)

func main() {
	s := []string{"Go", "Bravo", "Gopher", "Alpha", "Grin", "Delta"}
	sort.Strings(s)
	fmt.Println(s)
    // 从大到小进行排序
	sort.Sort(sort.Reverse(sort.StringSlice(s)))
	fmt.Println(s)
}

3. 对结构体进行排序,可以使用sort.Sort()函数对结构体进行排序,使用Sort函数需要实现Sort接口中的三个方法,下面是对nums中数字的出现次数进行计数,并且按照出现次数从大到小排序输出结果:

package main

import (
	"fmt"
	"sort"
)

// 使用type关键字定义一个结构体和结构体切片mp, key为数字, value为数字的出现次数
type pair struct{ key, value int }

// 切片中的每一个元素都是一个结构体
type mp []pair

// 实现Sort接口中的三个方法
func (m mp) Len() int { return len(m) }

func (m mp) Less(i, j int) bool { return m[i].value > m[j].value }

func (m mp) Swap(i, j int) { m[i], m[j] = m[j], m[i] }

func main() {
	nums := []int{1, 1, 3, 3, 3, 3, 2, 7, 7, 8, 8, 8, 9}
	// 统计每一个数的出现次数并且按照出现次数由大到小进行排序
	count := make(map[int]int)
	for i := 0; i < len(nums); i++ {
		count[nums[i]] += 1
	}
	// 声明一个结构体切片a
	var a []pair
	// 遍历map, 将键值对存储到结构体切片中
	for k, v := range count {
		a = append(a, pair{k, v})
	}
	// 使用sort.Sort方法进行排序
	sort.Sort(mp(a))
	fmt.Println(a)
}

第二种对结构体排序的方法可以使用sort.Slice()函数,类似于对int类型的切片进行排序,需要传递一个匿名函数,函数中实现类似于Sort接口中Less函数的功能:

package main

import (
	"fmt"
	"sort"
)

type pair struct{ key, value int }

func main() {
	nums := []int{1, 1, 3, 3, 3, 3, 2, 7, 7, 8, 8, 8, 9}
	count := make(map[int]int)
	for i := 0; i < len(nums); i++ {
		count[nums[i]] += 1
	}
	var a []pair
	for k, v := range count {
		a = append(a, pair{k, v})
	}
    // 使用sort.Slice()函数比较方便的一点是代码比较短, 写起来比较方便
	sort.Slice(a, func(i, j int) bool {
		return a[i].value > a[j].value
	})
	fmt.Println(a)
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/621771.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-15
下一篇 2022-04-15

发表评论

登录后才能评论

评论列表(0条)

保存