2025-03-19 14:36:09 +08:00

3.7 KiB

在 Go 语言中,sort 包提供了用于对切片和用户自定义数据集进行排序的功能。以下是一些常用的 sort 包函数及其使用方法:


1. 基本类型切片排序

  • Ints(a []int)
    对整数切片进行升序排序。
    示例:

    nums := []int{3, 1, 4, 2}
    sort.Ints(nums)
    fmt.Println(nums) // 输出: [1 2 3 4]
    
  • Float64s(a []float64)
    对浮点数切片进行升序排序。
    示例:

    nums := []float64{3.5, 1.2, 4.8, 2.1}
    sort.Float64s(nums)
    fmt.Println(nums) // 输出: [1.2 2.1 3.5 4.8]
    
  • Strings(a []string)
    对字符串切片进行升序排序(按字典顺序)。
    示例:

    strs := []string{"banana", "apple", "cherry"}
    sort.Strings(strs)
    fmt.Println(strs) // 输出: [apple banana cherry]
    

2. 判断是否已排序

  • IntsAreSorted(a []int) bool
    判断整数切片是否已经按升序排序。
    示例:

    nums := []int{1, 2, 3, 4}
    result := sort.IntsAreSorted(nums)
    fmt.Println(result) // 输出: true
    
  • Float64sAreSorted(a []float64) bool
    判断浮点数切片是否已经按升序排序。

  • StringsAreSorted(a []string) bool
    判断字符串切片是否已经按字典顺序排序。


3. 自定义排序

对于自定义结构体或复杂数据类型的排序,需要实现 sort.Interface 接口,该接口包含以下三个方法:

  • Len() int:返回集合的长度。
  • Less(i, j int) bool:定义排序规则,通常是比较索引 ij 的元素。
  • Swap(i, j int):交换索引 ij 的元素。

示例:

package main

import (
	"fmt"
	"sort"
)

type Person struct {
	Name string
	Age  int
}

type ByAge []Person

func (a ByAge) Len() int           { return len(a) }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }

func main() {
	people := []Person{
		{"Alice", 30},
		{"Bob", 25},
		{"Charlie", 35},
	}
	sort.Sort(ByAge(people))
	fmt.Println(people) // 输出: [{Bob 25} {Alice 30} {Charlie 35}]
}

4. 稳定排序

  • Stable(data Interface)
    使用稳定的排序算法对数据进行排序。稳定排序保证相等元素的相对顺序不变。
    示例:
    people := []Person{
        {"Alice", 30},
        {"Bob", 30},
        {"Charlie", 25},
    }
    sort.Stable(ByAge(people))
    fmt.Println(people) // 输出: [{Charlie 25} {Alice 30} {Bob 30}]
    

5. 查找操作

  • SearchInts(a []int, x int) int
    在已排序的整数切片中查找值 x,返回其索引。如果未找到,则返回应该插入的位置以保持排序。
    示例:

    nums := []int{1, 3, 5, 7}
    index := sort.SearchInts(nums, 4)
    fmt.Println(index) // 输出: 2
    
  • SearchStrings(a []string, x string) int
    在已排序的字符串切片中查找值 x

  • SearchFloat64s(a []float64, x float64) int
    在已排序的浮点数切片中查找值 x


6. 自定义切片排序

  • Slice(slice interface{}, less func(i, j int) bool)
    对任意类型的切片进行排序,通过传入一个比较函数 less 来定义排序规则。
    示例:
    nums := []int{3, 1, 4, 2}
    sort.Slice(nums, func(i, j int) bool {
        return nums[i] > nums[j] // 按降序排序
    })
    fmt.Println(nums) // 输出: [4 3 2 1]
    

7. 其他功能

  • Reverse(data Interface)
    对已排序的数据进行逆序排列。
    示例:
    nums := []int{1, 2, 3, 4}
    sort.Sort(sort.Reverse(sort.IntSlice(nums)))
    fmt.Println(nums) // 输出: [4 3 2 1]