Go语言实战案例-快速排序实现

简介: 快速排序是一种高效的排序算法,平均时间复杂度为O(n log n),采用分治法实现,适合递归教学与工程实践。本文介绍了快速排序的基本原理、Go语言实现方式、泛型扩展及使用示例,帮助读者掌握其核心思想与应用技巧。

 

排序算法是数据结构与算法中的核心内容,而**快速排序(Quick Sort)**则是其中效率非常高的一种。它在平均情况下的时间复杂度为 O(n log n),并且采用分治法实现,非常适合递归思想教学与工程实践。


一、快速排序简介

快速排序通过以下步骤实现:

  1. 1. 从数组中选取一个基准元素(pivot)
  2. 2. 将比它小的元素放左边,比它大的放右边(分区 partition
  3. 3. 对左子数组和右子数组递归排序

特点:

  • • 时间复杂度:
  • • 最优:O(n log n)
  • • 最坏:O(n²)(极端不均匀划分时)
  • • 空间复杂度:O(log n)(递归调用栈)
  • • 排序方式:原地排序、非稳定排序

二、Go语言实现快速排序(整数切片)

我们先实现一个基础版:排序 []int 切片。

1. 快速排序函数

package sortalgo
func QuickSort(arr []int) {
    if len(arr) < 2 {
        return
    }
    quickSort(arr, 0, len(arr)-1)
}

2. 递归核心逻辑

func quickSort(arr []int, left, right int) {
    if left >= right {
        return
    }
    pivotIndex := partition(arr, left, right)
    quickSort(arr, left, pivotIndex-1)
    quickSort(arr, pivotIndex+1, right)
}

3. 分区函数(Lomuto 分区法)

func partition(arr []int, left, right int) int {
    pivot := arr[right]  // 选取最后一个元素作为 pivot
    i := left - 1         // i 代表小于 pivot 的边界
    for j := left; j < right; j++ {
        if arr[j] <= pivot {
            i++
            arr[i], arr[j] = arr[j], arr[i]
        }
    }
    arr[i+1], arr[right] = arr[right], arr[i+1]  // 把 pivot 放到正确位置
    return i + 1
}

三、使用示例

package main
import (
    "fmt"
    "sortalgo"
)
func main() {
    arr := []int{9, 2, 5, 3, 7, 1, 8}
    fmt.Println("原始数组:", arr)
    
    sortalgo.QuickSort(arr)
    
    fmt.Println("排序后:", arr)
}

输出:

原始数组: [9 2 5 3 7 1 8]
排序后: [1 2 3 5 7 8 9]

四、进阶扩展

✅ 泛型版本(Go 1.18+)

如果你想让快速排序支持任意类型,比如 []float64[]string,可以用泛型 + 比较函数:

func QuickSortGeneric[T any](arr []T, less func(a, b T) bool) {
    var qsort func(left, right int)
    qsort = func(left, right int) {
        if left >= right {
            return
        }
        pivot := arr[right]
        i := left - 1
        for j := left; j < right; j++ {
            if less(arr[j], pivot) {
                i++
                arr[i], arr[j] = arr[j], arr[i]
            }
        }
        arr[i+1], arr[right] = arr[right], arr[i+1]
        pivotIndex := i + 1
        qsort(left, pivotIndex-1)
        qsort(pivotIndex+1, right)
    }
    if len(arr) > 1 {
        qsort(0, len(arr)-1)
    }
}

调用示例:

QuickSortGeneric([]string{"pear", "apple", "banana"}, func(a, b string) bool {
    return a < b
})

五、总结

通过本篇实战,你已经掌握了:

  • • 快速排序的核心原理:选 pivot、分区、递归排序
  • • 如何用 Go 语言实现快速排序
  • • 如何扩展成泛型排序函数,适用于不同类型数据

快速排序是许多语言标准库(包括 Go sort 包)中核心排序算法的底层实现之一,掌握它对理解排序机制和编写高效代码至关重要。

 

相关文章
|
2月前
|
Linux Go iOS开发
Go语言100个实战案例-进阶与部署篇:使用Go打包生成可执行文件
本文详解Go语言打包与跨平台编译技巧,涵盖`go build`命令、多平台构建、二进制优化及资源嵌入(embed),助你将项目编译为无依赖的独立可执行文件,轻松实现高效分发与部署。
|
3月前
|
数据采集 数据挖掘 测试技术
Go与Python爬虫实战对比:从开发效率到性能瓶颈的深度解析
本文对比了Python与Go在爬虫开发中的特点。Python凭借Scrapy等框架在开发效率和易用性上占优,适合快速开发与中小型项目;而Go凭借高并发和高性能优势,适用于大规模、长期运行的爬虫服务。文章通过代码示例和性能测试,分析了两者在并发能力、错误处理、部署维护等方面的差异,并探讨了未来融合发展的趋势。
321 0
|
2月前
|
存储 前端开发 JavaScript
Go语言实战案例-项目实战篇:编写一个轻量级在线聊天室
本文介绍如何用Go语言从零实现一个轻量级在线聊天室,基于WebSocket实现实时通信,支持多人消息广播。涵盖前后端开发、技术选型与功能扩展,助你掌握Go高并发与实时通信核心技术。
|
3月前
|
负载均衡 监控 Java
微服务稳定性三板斧:熔断、限流与负载均衡全面解析(附 Hystrix-Go 实战代码)
在微服务架构中,高可用与稳定性至关重要。本文详解熔断、限流与负载均衡三大关键技术,结合API网关与Hystrix-Go实战,帮助构建健壮、弹性的微服务系统。
457 1
微服务稳定性三板斧:熔断、限流与负载均衡全面解析(附 Hystrix-Go 实战代码)
|
3月前
|
安全 Go 开发者
Go语言实战案例:使用sync.Mutex实现资源加锁
在Go语言并发编程中,数据共享可能导致竞态条件,使用 `sync.Mutex` 可以有效避免这一问题。本文详细介绍了互斥锁的基本概念、加锁原理及实战应用,通过构建并发安全的计数器演示了加锁与未加锁的区别,并封装了一个线程安全的计数器结构。同时对比了Go中常见的同步机制,帮助开发者理解何时应使用 `Mutex` 及其注意事项。掌握 `Mutex` 是实现高效、安全并发编程的重要基础。
|
3月前
|
数据采集 Go API
Go语言实战案例:使用context控制协程取消
本文详解 Go 语言中 `context` 包的使用,通过实际案例演示如何利用 `context` 控制协程的生命周期,实现任务取消、超时控制及优雅退出,提升并发程序的稳定性与资源管理能力。
|
3月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
3月前
|
Go 开发者
Go语言实战案例:使用select监听多个channel
本文为《Go语言100个实战案例 · 网络与并发篇》第5篇,详解Go并发核心工具`select`的使用。通过实际案例讲解如何监听多个Channel、实现多任务处理、超时控制和非阻塞通信,帮助开发者掌握Go并发编程中的多路异步事件处理技巧。
|
1月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
156 1
|
3月前
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
286 1