Go语言排序

对于 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)

	b := [][]int{{1, 2}, {0, 3}, {-1, 5}, {-1, 4}}
	sort.Slice(b, func(i, j int) bool {
		return b[i][0] <= b[i][1]
	})
	fmt.Println("二维切片b的排序结果: ")
	for i := 0; i < len(b); i++ {
		for j := 0; j < len(b[0]); j++ {
			fmt.Print(b[i][j], " ")
		}
		fmt.Println()
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值