几种常用的排序代码
简单的代码
在我的笔记里面找到几种常用的排序代码,包括“冒泡排序、选择排序、二分排序、快速排序”。关于这些排序的原理,我之前是有专门研究的,网上也有很多教程。
copypackage main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
s := randInt(20)
BubblingSort(s, len(s))
fmt.Println(s)
s = randInt(20)
SelectSort(s, len(s))
fmt.Println(s)
s = randInt(20)
BisectionSort(s, len(s))
fmt.Println(s)
s = randInt(20)
quickSort(s, 0, len(s)-1)
fmt.Println(s)
}
func randInt(n int) []int {
res := make([]int, n)
for i := 0; i < n; i++ {
res[i] = rand.Intn(100)
}
return res
}
func BubblingSort(nums []int, ln int) {
for i := 0; i < ln-1; i++ {
flag := true
for j := 0; j < ln-i-1; j++ {
if nums[j] > nums[j+1] {
nums[j], nums[j+1] = nums[j+1], nums[j]
flag = false
}
}
if flag {
break // 已经有序,不用继续
}
}
}
func SelectSort(nums []int, ln int) {
for i := 0; i < ln; i++ {
min := i
for j := i + 1; j < ln; j++ {
if nums[min] > nums[j] {
min = j
}
}
nums[i], nums[min] = nums[min], nums[i]
}
}
func BisectionSort(nums []int, ln int) {
for i := 1; i < ln; i++ {
tmp := nums[i]
low, mid, high := 0, -1, i-1
for low <= high {
mid = (low + high) / 2
if tmp < nums[mid] {
high = mid - 1
} else {
low = mid + 1
}
}
for j := i - 1; j >= low; j-- {
nums[j+1] = nums[j]
}
if low != i {
nums[low] = tmp
}
}
}
func quickSort(num []int, low, high int) {
s, e, k := low, high, num[low]
for e > s {
for e > s && num[e] >= k {
e--
}
if num[e] <= k {
num[s], num[e] = num[e], num[s]
}
for e > s && num[s] <= k {
s++
}
if num[s] >= k {
num[s], num[e] = num[e], num[s]
}
if s > low {
quickSort(num, low, s-1)
}
if e < high {
quickSort(num, e+1, high)
}
}
}
使用go自带的排序
对[]int类型排序
copypackage main
import (
"fmt"
"math/rand"
"sort"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
s := randInt(20)
sort.Ints(s)
fmt.Println(s)
}
func randInt(n int) []int {
res := make([]int, n)
for i := 0; i < n; i++ {
res[i] = rand.Intn(100)
}
return res
}
对[]float64类型排序
copypackage main
import (
"fmt"
"math/rand"
"sort"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
s := randFloat64(20)
sort.Float64s(s)
fmt.Println(s)
}
func randFloat64(n int) []float64 {
res := make([]float64, n)
for i := 0; i < n; i++ {
res[i] = rand.Float64()
}
return res
}
对[]string类型排序
copypackage main
import (
"encoding/base64"
"fmt"
"math/rand"
"sort"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
s := randString(20)
sort.Strings(s)
fmt.Println(s)
}
func randString(n int) []string {
res := make([]string, n)
tmp := make([]byte, 10)
for i := 0; i < n; i++ {
rand.Read(tmp)
res[i] = base64.StdEncoding.EncodeToString(tmp)
}
return res
}
自定义类型排序
对于自定义类型,需要实现Less
、Swap
、Len
这三个sort包的接口,然后直接使用sort.Sort
方法就可以了。
copypackage main
import (
"encoding/base64"
"fmt"
"math/rand"
"sort"
)
func main() {
peoples := SortPeople{
{
name: "张三",
age: 25,
}, {
name: "李四",
age: 18,
}, {
name: "王五",
age: 20,
},
}
sort.Sort(peoples)
fmt.Println(peoples)
}
type (
people struct {
name string
age int
}
SortPeople []people
)
func (d SortPeople) Less(i, j int) bool {
return d[i].age < d[j].age
}
func (d SortPeople) Swap(i, j int) {
d[i], d[j] = d[j], d[i]
}
func (d SortPeople) Len() int {
return len(d)
}
便携的用法sort.Slice
直接使用sort.Slice只需要定义less func(i, j int) bool
方法就可以完成排序,代码是通过快速排序完成,不过具体实现加了反射,性能稍微有影响。
copypackage main
import (
"encoding/base64"
"fmt"
"math/rand"
"sort"
)
func main() {
peoples := []people{
{
name: "张三",
age: 25,
}, {
name: "李四",
age: 18,
}, {
name: "王五",
age: 20,
},
}
sort.Slice(peoples, func(i, j int) bool {
return peoples[i].age < peoples[j].age
})
fmt.Println(peoples)
}
便携的用法sort.SliceStable
该方法类似上一个方法,我看具体实现是使用一个稳定的排序算法。
copypackage main
import (
"encoding/base64"
"fmt"
"math/rand"
"sort"
)
func main() {
peoples := []people{
{
name: "张三",
age: 25,
}, {
name: "李四",
age: 18,
}, {
name: "王五",
age: 20,
},
}
sort.SliceStable(peoples, func(i, j int) bool {
return peoples[i].age < peoples[j].age
})
fmt.Println(peoples)
}
总结
排序算法是算法的基础,理解算法具体实现有利于锻炼思维,以及通过分析排序的优缺点,在合适的时候使用合适的排序方法。最重要的是高效和节省资源的平衡,通过研究go自带的排序包,发现官方排序会根据数据量将排序分成不同的方式进行,不过最重要的还是快速排序。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~