当前位置: 首页 > article >正文

Go 语言标准库中sort模块详细功能介绍与示例

Go语言的 sort 模块提供了对切片和自定义数据结构的排序功能,支持基本类型排序、自定义排序规则、稳定排序和二分查找。以下是 sort 模块的核心方法及示例说明:


1. 基本类型排序

sort.Intssort.Float64ssort.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.Slicesort.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 接口

通过实现 LenLessSwap 方法,自定义数据结构的排序逻辑。

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}]
}

总结

  • 核心方法
    • 基本排序IntsFloat64sStrings
    • 自定义排序SliceSliceStableSort(需实现 sort.Interface)。
    • 逆序排序Reverse
    • 检查排序IsSorted
    • 二分查找Search
  • 适用场景
    • 对基本类型切片快速排序。
    • 按自定义规则排序结构体切片。
    • 在有序数据中高效查找元素。
  • 注意事项
    • sort.Slice 更灵活,无需实现完整接口。
    • sort.Search 要求切片必须已按升序排列。

http://www.kler.cn/a/612852.html

相关文章:

  • 【学Rust写CAD】16 零标记类型(zero.rs)
  • LogitsProcessor代码分析
  • 3.28日,NBA,欧篮联全扫盘,太阳VS森林狼
  • 小林coding-10道Java集合面试题
  • 深入理解 dispatchEvent:前端事件触发的艺术
  • DPO介绍+公式推理
  • C++中的智能指针
  • Spring Boot深度解析:从核心原理到最佳实践
  • 美颜SDK架构解析:如何高效处理人脸美型的计算任务?
  • kubernetes》》k8s》》 kubeadm、kubectl、kubelet
  • [原创](Modern C++)现代C++的关键性概念: 如何利用多维数组的指针安全地遍历所有元素
  • NoSQL 数据库的适用场景与局限性分析
  • 7.5考研408数据结构散列表专题深度解析
  • Java EE 进阶:MyBatis-plus
  • SQL 复杂查询和性能优化
  • ubuntu 2204键盘按键映射修改
  • nginx部署前端项目(linux、docker)
  • 解锁大语言模型潜力:LangChain,构建AI应用的全新框架
  • Angular由一个bug说起之十五:自定义基于Overlay的Tooltip
  • 数字人分身生成50语种发布会视频技术架构深度解析