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

图解快速排序C语言实现

1 快速排序

快速排序(Quick Sort)是由英国计算机科学家Tony Hoare于1959年提出的一种高效的排序算法。

1.1 基本概念与理解

快速排序采用‌分治策略‌(Divide and Conquer)将问题分解为更小的子问题来解决。快速排序的核心思想是:
1‌.选取基准值(pivot)‌:从待排序序列中选择一个元素作为基准
2‌.分区操作(partition)‌:将序列重新排列,所有比基准值小的元素放在基准前面,比基准值大的元素放在基准后面
‌3.递归排序‌:对基准值左右两个子序列递归地进行快速排序
快速排序是‌原地排序算法‌,不需要额外的存储空间,平均情况下具有极佳的性能表现。

1.2 算法执行过程

初始调用阶段
‌1.初始参数‌:首次调用时left=0(数组起始),right=n-1(数组末尾)
‌2.终止检查‌:检查left>=right条件,防止空数组或单元素数组
分区过程详解
1‌.基准选择‌:计算中间索引(left+right)/2并取该位置元素作为基准值p
‌2.双指针初始化‌
(1)i从最左端(left)开始向右扫描
(2)j从最右端(right)开始向左扫描
3.扫描阶段‌
(1)左指针i向右移动,直到找到≥p的元素
(2)右指针j向左移动,直到找到≤p的元素
‌4.元素交换‌
(1)当i和j都停止时,若i <= j则交换arr[i]和arr[j]
(2)交换后同时移动两个指针(i++, j–)
递归调用阶段
‌1.分区完成‌:当i越过j时,数组被划分为三部分:
[left…j]:所有元素≤基准值
[i…right]:所有元素≥基准值
中间重叠区已有序
‌2.递归排序‌
先对左子数组[left…j]递归调用quick_sort
再对右子数组[i…right]递归调用quick_sort
执行示例(数组[5,2,9,3,7])
1.第一次调用‌
基准p=9(中间元素)
分区后:[5,2,7,3,9]
递归调用左[5,2,7,3]和右[9]
‌2.左子数组[5,2,7,3]‌
基准p=2(中间元素)
分区后:[2,5,7,3]
递归调用左[2]和右[5,7,3]
‌3.右子数组[5,7,3]‌
基准p=7
分区后:[5,3,7]
递归调用左[5,3]和右[7]
‌4.最终结果‌:所有递归完成后得到有序数组[2,3,5,7,9]

1.3 算法复杂度分析

1.时间复杂度
最优情况‌:每次分区都能将数组均分为两部分,递归树高度为log₂n,每层比较次数为n,时间复杂度为O(nlogn)
平均情况‌:随机化版本的快速排序平均时间复杂度为O(nlogn)
最坏情况‌:当数组已有序或逆序时,每次分区只能减少一个元素,时间复杂度退化为O(n²)
2.空间复杂度
快速排序是原地排序,不需要额外存储空间
递归调用栈的深度决定了空间复杂度:
最优情况:O(log n)
最坏情况:O(n)
3. 稳定性分析
快速排序是‌不稳定‌的排序算法,因为在分区过程中,相等元素的相对位置可能会改变。

1.4 C语言实现快速排序

#include <stdio.h>#define SORT_DATA_TYPE int/*** @brief 打印数据** @param arr 数组* @param n 数组元素个数*/
void print_array(int arr[], int n)
{int i;for (i = 0; i < n; i++){printf("%d ", arr[i]);}printf("\n");
}/*** @brief 快速排序** @param arr 待排序的数组* @param left 数组的左边界索引* @param right 数组的右边界索引*/
void quick_sort(SORT_DATA_TYPE arr[], int left, int right)
{int i = left;int j = right;SORT_DATA_TYPE p = arr[(left + right) / 2];SORT_DATA_TYPE temp;if (left >= right){/* 排序完成 */return;}while (i <= j){/*把小于中间基准值的数放到数组左边把大于中间基准值的数放到数组右边*/while (arr[i] < p){i++;}while (arr[j] > p){j--;}if (i <= j){/*交换数据,即小的放左边,大的放右边*/temp = arr[i];arr[i] = arr[j];arr[j] = temp;i++;j--;}}print_array(&arr[left], right - left + 1); /* 打印数组,调试使用 */quick_sort(arr, left, j);quick_sort(arr, i, right);
}int main()
{SORT_DATA_TYPE arr[] = {4, 3, 2, 1};int n = sizeof(arr) / sizeof(arr[0]);printf("old arr : ");print_array(arr, n);quick_sort(arr, 0, n - 1);printf("new arr : ");print_array(arr, n);return 0;
}


不同类型的数组直接将SORT_DATA_TYPE全部替换为需要的类型,然后删除多余的宏定义即可支持任意类型数组的快速排序。

1.5 简单测试

通过使用数组[4,3,2,1]演示快速排序的执行过程:
在这里插入图片描述
可以使用如下图片演示这一过程:
在这里插入图片描述

http://www.xdnf.cn/news/1325341.html

相关文章:

  • “道法术器” 思维:解析华为数字化转型
  • Lua学习记录 - 自定义模块管理器
  • 数据库:表和索引结构
  • 如何新建一个自己的虚拟环境
  • 实践笔记-小端模式下的寄存器数据输入技巧;图形化界面配置注意事项。
  • AI应用商业化加速落地 2025智能体爆发与端侧创新成增长引擎
  • 安装pnpm i -D @types/wechat-miniprogram报错,版本不匹配
  • 继承——Java中的“家族传承”
  • JavaSE高级-02
  • Read Frog:一款开源AI浏览器语言学习扩展
  • 网络基础——协议认识
  • 视觉语言导航(2)——VLN RNN TRANSFORMER 与ATTENTION 2.2+LSTM(单独一节)
  • 构建情感智能体:下一代AI心理助手的架构与实践
  • Lucene 8.5.0 的 `.pos` 文件**逻辑结构**
  • 基于JS实现的中国象棋AI系统:多模块协同决策与分析
  • leetcode4_452 and 763
  • 一道同分排名的SQL题
  • Django开发Web应用
  • Dubbo 的SPI
  • 15.三数之和
  • vue3 el-table-column 列头添加 图标按钮
  • 使用websockets中的一些问题和解决方法
  • day25|学习前端js
  • Day7--滑动窗口与双指针--1695. 删除子数组的最大得分,2958. 最多 K 个重复元素的最长子数组,2024. 考试的最大困扰度
  • JavaSE——高级篇
  • Java面试宝典:Redis 入门与应用
  • Poisson分布:稀有事件建模的理论基石与演进
  • 用随机森林填补缺失值:原理、实现与实战
  • 力扣hot100:移动零问题的巧妙解决:双指针与原地交换策略(283)
  • 开发避坑指南(28):Spring Boot端点检查禁用失效解决方案