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

数据结构-快速排序

一.概要

快速排序是一种基于分治思想的排序算法,其基本思路是选取一个基准值(pivot),通过一趟排序将待排序列分成两个部分,其中左半部分都小于基准值,右半部分都大于基准值,然后对左右两部分分别递归地进行快速排序,最终得到有序序列。

具体的实现过程如下:

  1. 选取基准值

任意选定一个数作为基准值。

  1. 分割操作

设定两个指针,左指针和右指针,分别指向序列的开头和结尾。从右指针开始向左扫描,找到第一个小于基准值的元素,将其与左指针所指的元素交换位置。然后从左指针开始向右扫描,找到第一个大于基准值的元素,将其与右指针所指的元素交换位置。重复以上过程,直到左指针与右指针相遇,此时将基准值与相遇位置的元素交换。

  1. 递归操作

递归地对左右两部分分别进行快速排序,直到每个部分只有一个元素或为空。

最终得到一个有序序列。

快速排序的时间复杂度是 O(nlogn),平均情况下比较快,最坏情况下为 O(n^2),是一种不稳定的排序算法。在实际应用中,可以通过随机选择基准值、三数取中等方法来避免出现最坏情况,提高排序效率。

二、代码实现

int  GetMidNumi(int* a, int left, int right)
{int mid = (left + right) / 2;if (a[left]<a[mid]){if (a[mid]<a[right]){return mid;}else if (a[left]>a[right]){return left;}else{return right;}}else{if (a[mid]>a[right]){return mid;}else if(a[left]<a[right]){return left;}else{return right;}}
}void QuickSort(int* a, int left, int right){if (left > right)return;int begin = left, end = right;//随机选KEY//int randi = left + (rand() % (right - left));//Swap(&a[left], &a[randi]);//三数取中int midi = GetMidNumi(a, left, right);Swap( &a[midi], &a[left]);int keyi = left;while (left < right){//右边找小while (left < right && a[right] >= a[keyi])--right;//左边找大while (left < right && a[left] <= a[keyi])++left;Swap(&a[left], &a[right]);}Swap(&a[keyi], &a[left]);keyi = left;QuickSort(a, begin, keyi - 1);QuickSort(a, keyi + 1, end);
}

这段代码是实现快速排序的程序,具体工作流程如下:

  1. 选取关键字 keyi,一般选择序列中的第一个元素。
  2. 从序列的两端开始搜索,右边找到小于keyi的元素,左边找到大于keyi的元素,然后交换这两个元素的位置。
  3. 继续执行步骤2,直到左右指针相遇。
  4. 将关键字 keyi 与相遇位置的元素交换位置。
  5. 递归地对左右两部分分别进行快速排序。

在实现过程中,该程序使用了三数取中的方法来选择关键字,避免了最坏情况的发生。同时,在搜索元素时,也采用了双向搜索的方法,提高了排序效率。

整个快速排序的时间复杂度为 O(nlogn),最坏情况下为 O(n^2),空间复杂度为 O(logn),是一种高效的排序算法。

三、总结

快速排序是一种基于分治思想的排序算法。其基本思想是选取一个基准值,通过一趟排序将待排序列分成两个部分,其中左半部分都小于基准值,右半部分都大于基准值,然后对左右两部分分别递归地进行快速排序,最终得到有序序列。

快速排序具有以下优点:

  1. 时间复杂度较低:平均时间复杂度为 O(nlogn),在实践中表现良好,较适合大规模数据的排序。

  2. 空间复杂度较低:空间复杂度为 O(logn),不需要额外的存储空间,能够节省内存。

  3. 实现简单:快速排序的实现比较简单,易于理解和掌握。

但是快速排序也存在以下缺点:

  1. 最坏情况下时间复杂度较高:在某些特殊情况下,如原序列已经排好序或基准值选择不当时,快速排序的时间复杂度会退化到 O(n^2)。

  2. 不适合稳定性排序:由于交换过程不一定保证元素的相对位置不变,因此快速排序不适合对序列中有相同元素的数据进行排序。

针对上述缺点,可以采用以下方法来改进快速排序:

  1. 随机选取基准值:避免最坏情况的发生,提高排序效率。

  2. 三数取中法选取基准值:通过选取序列头、尾和中间位置的元素的中位数作为基准值,避免最坏情况的发生,提高排序效率。

  3. 在小规模数据时采用插入排序:当待排序的子序列长度小于一定值时,采用插入排序代替快速排序,可以降低算法的时间复杂度。

http://www.lryc.cn/news/56627.html

相关文章:

  • WuThreat身份安全云-TVD每日漏洞情报-2023-04-10
  • IDEA中查看源码点击Download Sources时出现Cannot download sources的问题复现及解决
  • R+VIC模型融合实践技术应用及未来气候变化模型预测/SWAT/HSPF/HEC-HMS
  • Python 02 数据类型(04元组)
  • WMS:入库库作业流程状态定位
  • 蓝易云:Linux系统【Centos7】如何配置完整的CC攻击防护策略
  • 编解码持续升级,「硬」实力铸就视频云最优解
  • 贵金属技术分析的止损保护
  • Python 进阶指南(编程轻松进阶):三、使用 Black 工具来格式化代码
  • 计算机应用辅导大纲及真题
  • 【Go基础】一篇文章带你全面了解学习—切片
  • 2022国赛28:centos8.5离线安装docker
  • JVM专题
  • 蓝桥杯模板题目
  • SAP IDT - Building Data Foundation
  • 【Python】【进阶篇】三、Python爬虫的构建User-Agnet代理池
  • 数据结构.双链表的各种操作
  • 去年12月被无情辞退,三个月后我携手自动化测试神技王者归来
  • 区块链技术之共识机制
  • SpringCloud断路器——Hystrix
  • 分布式 - 分布式体系架构:集群和分布式
  • NodeJs常用内置模块
  • 4.0 功能抢先看 | 读懂一个项目的研发效能 之 项目人效
  • Object方法
  • 042:cesium加载Eris地图(多种形式)
  • 第十四届蓝桥杯大赛软件赛省赛(C/C++B组)
  • Python生成随机验证码
  • Longitudinal Change Detection on Chest X-rays Using Geometric Correlation Maps
  • 5年功能测试的一些心得
  • 在外包做了3年测试,离职后却成功入职字节跳动.....