Go語言的 sort
模塊提供了對切片和自定義數據結構的排序功能,支持基本類型排序、自定義排序規則、穩定排序和二分查找。以下是 sort
模塊的核心方法及示例說明:
1. 基本類型排序
sort.Ints
、sort.Float64s
、sort.Strings
直接對基本類型的切片進行排序。
package mainimport ("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 stringAge 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))) // 輸出: trueunsorted := []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
要求切片必須已按升序排列。