前言:
本文档旨在解答新手如何使用sort包的问题,尽量不涉及底层逻辑,对新入门的同学非常友好
一,sort包是什么?
- sort包是go语言中基础包之一,主要提供给用户进行排序的工具
- sort包主要针对[]int、[]float64、[]string、以及其他自定义切片的排序。(不只是对数字)
- sort 包 在内部实现了四种基本的排序算法:插入排序(insertionSort)、归并排序(symMerge)、堆排序(heapSort)和快速排序(quickSort);。
- sort 包会依据实际数据自动选择最优的排序算法。所以我们写代码时只需要考虑实现 sort.Interface 这个类型就可以了。
二,使用方法
(一)使用sort包的基本要求
- 声明满足接口的数据
- 使用方法
(二)实例说明
- 最原始的使用
package main
import (
"fmt"
"sort"
)
//方法不能改变,是定义好的
// 定义序列类型,只要此类型实现了sort.interface{}接口(实现三要素方法),就可以对此类型排序
type TestStringList []string
// 元素个数
func (t TestStringList) Len() int {
return len(t)
}
// 比较结果
func (t TestStringList) Less(i, j int) bool {
return t[i] < t[j]
}
// 交换方式
func (t TestStringList) Swap(i, j int) {
t[i], t[j] = t[j], t[i]
}
func main() {
stringList := TestStringList{
"1-php",
"2-java",
"3-golang",
"4-c",
"5-cpp",
"6-python",
}
//按照定义的规则排序
sort.Sort(stringList)
fmt.Println(stringList)
//返回值
//[1-php 2-java 3-golang 4-c 5-cpp 6-python]
//按照定义的规则反向排序
sort.Sort(sort.Reverse(stringList))
fmt.Println(stringList)
//返回值
//[6-python 5-cpp 4-c 3-golang 2-java 1-php]
}
- 不用写方法体,满足接口的其他方法
package main
import (
"fmt"
"sort"
)
func main() {
//直接定义字符串序列为StringSlice,让数据直接满足接口
stringTmp := sort.StringSlice{
"3-golang",
"4-c",
"5-cpp",
"1-php",
"2-java",
"6-python",
}
sort.Sort(stringTmp)
fmt.Println(stringTmp)
//[1-php 2-java 3-golang 4-c 5-cpp 6-python]
sort.Sort(sort.Reverse(stringTmp))
fmt.Println(stringTmp)
//[6-python 5-cpp 4-c 3-golang 2-java 1-php]
intTmp := []int{
6, 3, 9, 8, 1, 2, 5, 7,
}
//转换intTmp为IntSlice类型
sort.Sort(sort.IntSlice(intTmp))
fmt.Println(intTmp)
//[1 2 3 5 6 7 8 9]
sort.Sort(sort.Reverse(sort.IntSlice(intTmp)))
fmt.Println(intTmp)
//[9 8 7 6 5 3 2 1]
}
(三)sort包中的函数有那些
- 按照定义的规则排序:sort.Sort(stringList)
- 按照定义的规则反向排序:sort.Sort(sort.Reverse(stringList))
- 一个方法就可以正反向排序:sort.Slice()
package main
import (
"fmt"
"sort"
)
func main() {
a := []int{6, 3, 9, 8, 1, 2, 5, 7}
sort.Slice(a, func(i, j int) bool {
return a[i] < a[j]
//大于号改为小于号则改为正向排序
})
fmt.Println(a)
//[9 8 7 6 5 3 2 1]
}
- 多维排序:满足的接口不同
这里定义了一个描述编程语言的二维map切片,先按照type排序,然后按照name排序。
1,sort.interface{}实现
type langSlice []map[string]string
func (l langSlice) Len() int {
return len(l)
}
func (l langSlice) Less(i,j int) bool {
if l[i]["type"] != l[j]["type"] {
return l[i]["type"] < l[j]["type"]
}
return l[i]["name"] < l[j]["name"]
}
func (l langSlice) Swap(i,j int){
l[i],l[j] = l[j],l[i]
}
func demoMapSort(){
lang := langSlice{
{"type": "front-end", "name": "css"},
{"type": "after-end", "name": "php"},
{"type": "os", "name": "mac"},
{"type": "front-end", "name": "js"},
{"type": "os", "name": "ubuntu"},
{"type": "after-end", "name": "java"},
{"type": "front-end", "name": "html"},
{"type": "after-end", "name": "go"},
{"type": "os", "name": "windows"},
{"type": "after-end", "name": "python"},
{"type": "os", "name": "centos"},
}
sort.Sort(lang)
fmt.Println(lang)
//[map[name:go type:after-end] map[name:java type:after-end] map[name:php type:after-end] map[name:python type:after-end] map[name:css type:front-end] map[name:html type:front-end] map[name:js type:front-end] map[name:centos type:os] map[name:mac type:os] map[name:ubuntu type:os] map[name:windows type:os]]
}
2,sort.Slice实现
func demoMapSliceSort() {
//定义了语言切片
lang := []map[string]string{
{"type": "front-end", "name": "css"},
{"type": "after-end", "name": "php"},
{"type": "os", "name": "mac"},
{"type": "front-end", "name": "js"},
{"type": "os", "name": "ubuntu"},
{"type": "after-end", "name": "java"},
{"type": "front-end", "name": "html"},
{"type": "after-end", "name": "go"},
{"type": "os", "name": "windows"},
{"type": "after-end", "name": "python"},
{"type": "os", "name": "centos"},
}
sort.Slice(lang, func(i, j int) bool {
if lang[i]["type"] != lang[j]["type"] {
return lang[i]["type"] < lang[j]["type"]
}
return lang[i]["name"] < lang[j]["name"]
})
fmt.Println(lang)
}
- 同时你也发现里面还有 IntsAreSorted、Float64sAreSorted、StringsAreSorted。他就是返回一个切片是否已经是升序排序好了的布尔值,个人觉得比较鸡肋。
-
想要稳定,得实现Stable()函数 (但真的没有必要,还是前几个最好,)
//有兴趣就看看把,但并不建议
// 这里使用自定义的方式实现
package main
import (
"fmt"
"sort"
)
type paixua []int
func (x paixua) Len() int {
return len(x)
}
func (x paixua) Less(i, j int) bool {
return x[i] < x[j]
}
func (x paixua) Swap(i, j int) {
x[i], x[j] = x[j], x[i]
}
func main() {
a := paixua{2, 8, 3, 7, 9, 4, 1, 6}
fmt.Println("排序前", a)
sort.Stable(a)
fmt.Println("排序后", a)
}
三不同元素的排序原则
- int:1,2,3
- float64:1.1,1.2,2.3,2.4
- 字母:aa ,ab ,ba ,bb(大写字母大于小写字母,符合ascall码排序)
- 有兴趣可以看看
优秀的读者到这里总会点赞