0

0

Golang中的排序算法与使用_Golang排序包与排序实现技巧

P粉602998670

P粉602998670

发布时间:2026-02-07 13:50:44

|

870人浏览过

|

来源于php中文网

原创

Go 的 sort 包默认混合使用快排、插入排序和堆排;大数组用快排,子数组长度≤12时切插入排序,递归过深时退化为堆排以避免最坏O(n²),不保证稳定,需稳定排序应使用sort.Stable()。

golang中的排序算法与使用_golang排序包与排序实现技巧

Go 的 sort 包默认用什么排序算法

Go 标准库sort 包对切片排序时,底层混合使用了三种算法:quicksort(快排)、insertionsort(插入排序)和 heapsort(堆排)。具体策略是:对大数组用快排,当子数组长度 ≤12 时切换为插入排序(利用小数组局部有序性),若递归深度过深则退化为堆排防止最坏 O(n²)。这不是可配置项,而是硬编码sort.go 中的优化逻辑。

这意味着你调用 sort.Ints()sort.Slice() 时,无需关心算法选择——但要注意:它不保证稳定(相同元素相对位置可能改变),如需稳定排序得自己实现或改用 sort.Stable()

什么时候该用 sort.Slice() 而不是 sort.Sort()

sort.Slice() 是 Go 1.8 引入的便捷函数,适合绝大多数自定义排序场景;sort.Sort() 则要求你实现 sort.Interface(即 Len()Less()Swap() 三个方法),更重但更灵活。

  • sort.Slice():结构体切片按某个字段排序、嵌套字段、组合条件(比如先按 name 升序,再按 age 降序)
  • sort.Sort():需要复用同一套比较逻辑多次、或排序逻辑涉及复杂状态(如外部缓存、闭包捕获变量不方便传入)
  • 性能差异极小,但 sort.Slice() 内部仍会构造匿名接口,有轻微逃逸和接口调用开销;高频小切片排序可测一下实际影响

示例:按结构体字段排序

立即学习go语言免费学习笔记(深入)”;

type User struct {
    Name string
    Age  int
}
users := []User{{"Alice", 30}, {"Bob", 25}}
sort.Slice(users, func(i, j int) bool {
    return users[i].Age < users[j].Age // 升序
})

sort.SliceStable()sort.Stable()区别在哪?

sort.SliceStable() 是 Go 1.18 新增的,专为切片设计的稳定排序函数;而 sort.Stable() 接收任意实现了 sort.Interface 的类型。两者都保持相等元素的原始顺序。

Pascal基础教程 Pascal入门必备基础教程 CHM版
Pascal基础教程 Pascal入门必备基础教程 CHM版

无论做任何事情,都要有一定的方式方法与处理步骤。计算机程序设计比日常生活中的事务处理更具有严谨性、规范性、可行性。为了使计算机有效地解决某些问题,须将处理步骤编排好,用计算机语言组成“序列”,让计算机自动识别并执行这个用计算机语言组成的“序列”,完成预定的任务。将处理问题的步骤编排好,用计算机语言组成序列,也就是常说的编写程序。在Pascal语言中,执行每条语句都是由计算机完成相应的操作。编写Pascal程序,是利用Pasca

下载

关键区别在于使用门槛:

  • sort.SliceStable() 直接传切片 + 比较函数,写法和 sort.Slice() 一致,只是加了“稳定”保证
  • sort.Stable() 必须包装成接口,多一层类型转换,适合已封装好排序逻辑的类型(如自定义的 ByAge 类型)
  • 稳定排序比非稳定慢约 10%~30%,仅在业务语义要求必须保序时启用(例如分页查询中,两次排序结果需一致)

注意:稳定 ≠ 可预测的“绝对顺序”,它只保证“原序列中靠前的相等元素,在结果中仍靠前”。如果排序键本身不唯一且你依赖这个行为,就得确认输入顺序是否可控。

自定义类型排序时,为什么 Less() 返回 true 表示“i 应该排在 j 前面”?

这是 sort.Interface 的契约约定,不是直觉上的“大小比较”。很多初学者误写成 a[i] > a[j] 导致逆序,或混淆升序/降序逻辑。

  • 升序:返回 a[i]
  • 降序:返回 a[i] > a[j]
  • 多级排序:先比一级,相等再比二级,例如 u[i].Name != u[j].Name ? u[i].Name u[j].Age

最容易被忽略的是:浮点数比较不能直接用 == 判断相等性,应先用 math.Abs(a-b) 归一化,否则 Less() 在边界处行为不可靠,可能破坏排序稳定性甚至触发 panic(如 NaN 参与比较)。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

184

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

232

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

344

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

210

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

398

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

282

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

196

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

641

2025.06.17

Golang处理数据库错误教程合集
Golang处理数据库错误教程合集

本专题整合了Golang数据库错误处理方法、技巧、管理策略相关内容,阅读专题下面的文章了解更多详细内容。

2

2026.02.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 4.7万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号