对于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)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)