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

排序算法---快速排序

原创不易,转载请注明出处。欢迎点赞收藏~

快速排序是一种常用的排序算法,采用分治的策略来进行排序。它的基本思想是选取一个元素作为基准(通常是数组中的第一个元素),然后将数组分割成两部分,其中一部分的所有元素小于等于基准值,另一部分的所有元素大于基准值。然后对这两部分继续递归应用快速排序算法,直到整个数组有序。

算法步骤如下:

  1. 选择基准元素。
  2. 将数组分割成两部分,使得左半部分的元素都小于等于基准值,右半部分的元素都大于基准值。
  3. 对左右两部分分别应用快速排序算法(递归)。

快速排序的时间复杂度为O(nlogn)。这是因为每次划分操作会把待排序的序列分割成两个规模大致相等的子序列,划分操作的时间复杂度为O(n),递归调用的次数为O(logn)。所以总体的时间复杂度为O(nlogn)。

快速排序的空间复杂度为O(logn)。这是因为快速排序需要使用递归来进行划分操作,每一层递归都需要额外的空间来保存分割点的位置,递归调用的次数为O(logn),所以总体的空间复杂度为O(logn)。

需要注意的是,快速排序是一种原地排序算法,它不需要额外的辅助空间来进行排序。但是在实际实现中,为了提高排序的效率和减少递归深度,通常会使用一些优化策略,比如随机选择基准元素、三数取中法等。

#include <stdio.h>// 交换函数,用于交换数组中两个元素的位置
void swap(int *a, int *b)
{int temp = *a;*a = *b;*b = temp;
}// 分割函数,用于将数组分割成左右两部分
int partition(int arr[], int low, int high)
{int pivot = arr[low]; // 选择第一个元素作为基准值int i = low, j = high;while (i < j){// 从右往左找到第一个小于基准值的元素while (i < j && arr[j] >= pivot){j--;}// 从左往右找到第一个大于基准值的元素while (i < j && arr[i] <= pivot){i++;}// 交换这两个元素的位置if (i < j){swap(&arr[i], &arr[j]);}}// 将基准值放到最终的位置swap(&arr[low], &arr[i]);return i;
}// 快速排序函数
void quick_sort(int arr[], int low, int high)
{if (low < high){// 找到分割点int pivotIndex = partition(arr, low, high);// 对分割点左右两部分进行递归排序quick_sort(arr, low, pivotIndex - 1);quick_sort(arr, pivotIndex + 1, high);}
}// 测试
int main()
{int arr[] = {8, 4, 2, 9, 5, 1, 6, 3, 7};int n = sizeof(arr) / sizeof(arr[0]);printf("排序前的数组:\n");for (int i = 0; i < n; i++){printf("%d ", arr[i]);}quick_sort(arr, 0, n - 1);printf("\n排序后的数组:\n");for (int i = 0; i < n; i++){printf("%d ", arr[i]);}putchar('\n');return 0;
}

以上示例代码演示了如何使用快速排序算法对一个整数数组进行排序。首先定义了交换函数swap用于交换数组中两个元素的位置,然后定义了分割函数partition用于将数组分割成左右两部分。 最后定义了快速排序函数quick_sort来递归地进行分割和排序。

运行示例代码后,你可以看到以下输出:

相关文章:

  • 深度解析与推荐:主流Web前端开发框架
  • (52)只出现一次的数字III
  • 基于鲲鹏服务器的LNMP配置
  • 人类的协同不同于机器的协同
  • 旅游|基于Springboot的旅游管理系统设计与实现(源码+数据库+文档)
  • 前端图片转base64 方法
  • Aethir和Well-Link Tech携手革新云游戏,释放人工智能(AI)潜力
  • [当人工智能遇上安全] 11.威胁情报实体识别 (2)基于BiGRU-CRF的中文实体识别万字详解
  • 部署一个在线OCR工具
  • Redis(三)主从架构、Redis哨兵架构、Redis集群方案对比、Redis高可用集群搭建、Redis高可用集群之水平扩展
  • 【Web】基于Mybatis的SQL注入漏洞利用点学习笔记
  • Terraform实战(三)-在AWS上尝试Terraform的Vault Provider
  • MySQL用心总结
  • Linux嵌入式开发+驱动开发-中断
  • Kylin系统下Qt的各种中文问题解决思路
  • 分享的文章《人生如棋》
  • IndexedDB
  • JDK9: 集成 Jshell 和 Maven 项目.
  • LeetCode算法系列_0891_子序列宽度之和
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • 对JS继承的一点思考
  • 机器学习中为什么要做归一化normalization
  • 如何利用MongoDB打造TOP榜小程序
  • 使用agvtool更改app version/build
  • 手机端车牌号码键盘的vue组件
  • 网络应用优化——时延与带宽
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 函数计算新功能-----支持C#函数
  • ​configparser --- 配置文件解析器​
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (十一)手动添加用户和文件的特殊权限
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .net framework4与其client profile版本的区别
  • .NET 设计模式—适配器模式(Adapter Pattern)
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .net2005怎么读string形的xml,不是xml文件。
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .net用HTML开发怎么调试,如何使用ASP.NET MVC在调试中查看控制器生成的html?
  • .Net转前端开发-启航篇,如何定制博客园主题
  • @Conditional注解详解
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • @vue/cli脚手架
  • [2009][note]构成理想导体超材料的有源THz欺骗表面等离子激元开关——
  • [AX]AX2012 SSRS报表Drill through action
  • [BZOJ2850]巧克力王国
  • [ccc3.0][数字钥匙] UWB配置和使用(二)
  • [CQOI 2011]动态逆序对
  • [CSS]CSS 的背景
  • [daily][archlinux][game] 几个linux下还不错的游戏
  • [exgcd] Jzoj P1158 荒岛野人