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

C语言快速排序

什么是快速排序?

快速排序(Quick Sort)是一种高效的排序算法,采用"分治"策略。它的核心思想是:选择一个基准值(pivot),将数组分成两部分,一部分比基准值小,另一部分比基准值大,然后递归地对这两部分进行排序。

为什么选择前后指针法?

在快速排序的几种实现方法中(Hoare版本、前后指针、挖坑法),前后指针法相对容易理解。

前后指针法思路

  1. 选择最左边的元素作为基准值(key)
  2. 定义两个指针:prev(慢指针)和cur(快指针)
  3. cur先移动,如果cur指向的元素小于key,prev就前进并交换prev和cur指向的元素
  4. 当cur走到数组末尾,将key与prev指向的元素交换
  5. 递归处理key左边和右边的子数组

C语言实现代码

#include <stdio.h>// 交换两个元素的值
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}// 快速排序函数
void quickSort(int arr[], int left, int right) {// 递归终止条件:子数组长度小于等于1if (left >= right) {return;}// 选择最左边的元素作为基准值int key = arr[left];int prev = left;  // 慢指针int cur = left + 1;  // 快指针// cur移动,prev跟随while (cur <= right) {// 如果cur指向的元素小于基准值if (arr[cur] < key) {prev++;  // prev前进swap(&arr[cur], &arr[prev]);  // 交换cur和prev指向的元素}cur++;  // cur总是前进}// 将基准值放到正确位置swap(&arr[left], &arr[prev]);// 递归排序左右子数组quickSort(arr, left, prev - 1);quickSort(arr, prev + 1, right);
}// 打印数组
void printArray(int arr[], int size) {for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}printf("\n");
}int main() {int arr[] = {10, 7, 8, 9, 1, 5};int n = sizeof(arr) / sizeof(arr[0]);printf("原始数组: ");printArray(arr, n);quickSort(arr, 0, n - 1);printf("排序后数组: ");printArray(arr, n);return 0;
}
  1. swap函数:用于交换两个元素的值,是排序中常用的操作。

  2. quickSort函数

    • leftright表示当前要排序的子数组的左右边界
    • 选择最左边的元素作为基准值key
    • prev从基准值后一个位置开始,curprev的下一个位置开始
    • cur向前移动,如果遇到比key小的元素,prev就前进并交换prevcur指向的元素
    • cur走到数组末尾,将keyprev指向的元素交换
  3. 递归:将数组分成两部分,分别对左右子数组递归调用quickSort

快速排序的执行过程(以10, 7, 8, 9, 1, 5为例)

  1. 选择10作为基准值
  2. 从左到右遍历:7、8、9都比10小,1和5也比10小
  3. 遍历完成后,10应该放在第5个位置(索引4)
  4. 交换10和1,得到[1, 7, 8, 9, 10, 5]
  5. 递归排序[1, 7, 8, 9]和[5]

时间复杂度

最佳情况:O(n log n) - 每次都能将数组分成两个相等的子数组

最坏情况:O(n²) - 数组已经基本有序,每次只能减少一个元素

平均情况:O(n log n)。

1.递归的终止条件if (left >= right)很重要,避免无限递归。

2.注意cur的边界条件,要小于等于right

3.基准值的选择影响排序效率,这里选择最左边的元素是简化实现


文章转载自:

http://oGCxpsO9.qmrsf.cn
http://1fuMXvhU.qmrsf.cn
http://X4xQIqGD.qmrsf.cn
http://j468w6c3.qmrsf.cn
http://ZEeMjyKL.qmrsf.cn
http://x2b7YXga.qmrsf.cn
http://EO4nz43u.qmrsf.cn
http://Fc7evKKC.qmrsf.cn
http://92GtS9L3.qmrsf.cn
http://8XVuXMw3.qmrsf.cn
http://yfGmLLCF.qmrsf.cn
http://IkqsYNqx.qmrsf.cn
http://BNySVS8x.qmrsf.cn
http://o9mjh6lk.qmrsf.cn
http://UwCts5v0.qmrsf.cn
http://PKv4yKME.qmrsf.cn
http://Dm94pNxs.qmrsf.cn
http://LIsV1RCJ.qmrsf.cn
http://mpFGXMsB.qmrsf.cn
http://WD0mR61w.qmrsf.cn
http://rWB4WuD9.qmrsf.cn
http://d7IX2cTq.qmrsf.cn
http://vMV0gkxl.qmrsf.cn
http://2SNJK3lO.qmrsf.cn
http://w4CXpFf2.qmrsf.cn
http://H6pkxv31.qmrsf.cn
http://vyyCAy4x.qmrsf.cn
http://nV5RzgkA.qmrsf.cn
http://I3Qb4puT.qmrsf.cn
http://HeiJzGoO.qmrsf.cn
http://www.dtcms.com/a/373272.html

相关文章:

  • 软件可靠性失效严重程度分类与深度解析
  • 如何让dify分类器更加精准的分类?
  • C# Web API 前端传入参数时间为Utc
  • Python爬虫实战:研究3D plotting模块,构建房地产二手房数据采集和分析系统
  • sglang pytorch NCCL hang分析
  • langchain 缓存 Caching
  • Spark生态全景图:图计算与边缘计算的创新实践
  • 最长上升/下降子序列的长度(动态规划)
  • 自动驾驶中的传感器技术38——Lidar(13)
  • 计算机组成原理:计算机的分类
  • Spark SQL解析查询parquet格式Hive表获取分区字段和查询条件
  • 辨析——汇编 shell C语言
  • 免费的SSL和付费SSL 证书差异
  • 全新 Navicat On-Prem Server 3 正式上线,数据库云管理能力全面跃升
  • 华大 MCU 串口 PWM 控制方案完整笔记
  • 档案管理软件
  • Qoder 使用说明书,公测期免费体验
  • 实现自己的AI视频监控系统-第四章-基于langchain的AI大模型与智能体应用2
  • 消息队列-初识kafka
  • linux 100个问答81~101 主要是k8s相关
  • 【C++设计模式】第三篇:观察者模式(别名:发布-订阅模式、模型-视图模式、源-监听器模式)
  • OpenCV C++ 二值图像处理:阈值化技术全解析
  • OpenCV C++ 形态学分析:从基础操作到高级应用
  • 区块链里的 “信标” 是啥?
  • ROS与SDF/URDF的关系及其设计差异(为什么ROS不能直接调用sdf模型进行控制)
  • 15 种 HTTP 请求方法详解:从 GET/POST 核心方法到 WebDAV 扩展及Python实现示例
  • 2025年Q3 GEO服务市场全景:技术路径、行业实践与合规框架解析——兼谈GEO公司有哪些核心能力
  • 【Day 50 】Linux-nginx反向代理与负载均衡
  • 【多线程案例】:单例模式
  • JavaSE 异常从入门到面试:全面解析与实战指南