Go 语言标准库中sort模块详细功能介绍与示例
Go语言的 sort
模块提供了对切片和自定义数据结构的排序功能,支持基本类型排序、自定义排序规则、稳定排序和二分查找。以下是 sort
模块的核心方法及示例说明:
1. 基本类型排序
sort.Ints
、sort.Float64s
、sort.Strings
直接对基本类型的切片进行排序。
package main
import (
"fmt"
"sort"
)
func main() {
// 整数切片排序
ints := []int{3, 1, 4, 1, 5}
sort.Ints(ints)
fmt.Println(ints) // 输出: [1 1 3 4 5]
// 浮点数切片排序
floats := []float64{3.14, 2.71, 1.0}
sort.Float64s(floats)
fmt.Println(floats) // 输出: [1 2.71 3.14]
// 字符串切片排序(字典序)
strs := []string{"banana", "apple", "cherry"}
sort.Strings(strs)
fmt.Println(strs) // 输出: [apple banana cherry]
}
2. 自定义排序规则
sort.Slice
和 sort.SliceStable
通过自定义比较函数对切片排序。
sort.Slice
:不保证相等元素的顺序(非稳定排序)。sort.SliceStable
:保留相等元素的原始顺序(稳定排序)。
type Person struct {
Name string
Age int
}
func main() {
people := []Person{
{"Alice", 30},
{"Bob", 25},
{"Charlie", 35},
{"David", 25},
}
// 按年龄排序(非稳定)
sort.Slice(people, func(i, j int) bool {
return people[i].Age < people[j].Age
})
fmt.Println(people) // 输出顺序可能为 [Bob David Alice Charlie]
// 按年龄排序(稳定)
sort.SliceStable(people, func(i, j int) bool {
return people[i].Age < people[j].Age
})
fmt.Println(people) // 输出顺序保持 [Bob David Alice Charlie]
}
3. 实现 sort.Interface
接口
通过实现 Len
、Less
、Swap
方法,自定义数据结构的排序逻辑。
type PersonList []Person
// 实现 sort.Interface 接口
func (p PersonList) Len() int { return len(p) }
func (p PersonList) Less(i, j int) bool { return p[i].Age < p[j].Age }
func (p PersonList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func main() {
people := PersonList{
{"Alice", 30},
{"Bob", 25},
{"Charlie", 35},
}
sort.Sort(people)
fmt.Println(people) // 输出: [{Bob 25} {Alice 30} {Charlie 35}]
}
4. 逆序排序
sort.Reverse
反转排序逻辑,实现从大到小排序。
func main() {
ints := []int{3, 1, 4, 1, 5}
sort.Sort(sort.Reverse(sort.IntSlice(ints)))
fmt.Println(ints) // 输出: [5 4 3 1 1]
}
5. 检查是否已排序
sort.IsSorted
验证切片是否已按顺序排序。
func main() {
ints := []int{1, 2, 3}
fmt.Println(sort.IsSorted(sort.IntSlice(ints))) // 输出: true
unsorted := []int{3, 1, 2}
fmt.Println(sort.IsSorted(sort.IntSlice(unsorted))) // 输出: false
}
6. 二分查找
sort.Search
在已排序的切片中查找目标值,返回最小的满足条件的索引。
func main() {
ints := []int{1, 3, 5, 7, 9}
target := 5
// 查找第一个 >= target 的索引
index := sort.Search(len(ints), func(i int) bool {
return ints[i] >= target
})
if index < len(ints) && ints[index] == target {
fmt.Printf("找到 %d,索引为 %d\n", target, index) // 输出: 找到 5,索引为 2
} else {
fmt.Println("未找到")
}
}
7. 自定义复杂排序
结合多个字段排序。
func main() {
people := []Person{
{"Alice", 30},
{"Bob", 25},
{"Charlie", 30},
}
// 先按年龄排序,年龄相同按名字字典序排序
sort.Slice(people, func(i, j int) bool {
if people[i].Age == people[j].Age {
return people[i].Name < people[j].Name
}
return people[i].Age < people[j].Age
})
fmt.Println(people) // 输出: [{Bob 25} {Alice 30} {Charlie 30}]
}
总结
- 核心方法:
- 基本排序:
Ints
、Float64s
、Strings
。 - 自定义排序:
Slice
、SliceStable
、Sort
(需实现sort.Interface
)。 - 逆序排序:
Reverse
。 - 检查排序:
IsSorted
。 - 二分查找:
Search
。
- 基本排序:
- 适用场景:
- 对基本类型切片快速排序。
- 按自定义规则排序结构体切片。
- 在有序数据中高效查找元素。
- 注意事项:
sort.Slice
更灵活,无需实现完整接口。sort.Search
要求切片必须已按升序排列。