快速排序的思想与归并排序思想类似,都是采用分治法的思想。将一个数组A[l...r]使用快速排序可以分解为三个主要的步骤:

  1. 通过随机算法获得数组A中的一个下标k,将A[k]与A[r]交换。
  2. 将数组分解成左右两个数组,左边数组的值均小于A[r],右边数组的值均不小于A[r]。
  3. 分别对左右两个数组进行排序,这两个数组的大小均比A小。

  通过上面的步骤,我们就可以得到快速排序的一个框架:

1 void QuickSortCore(int data[], int start, int end)
2 {
3     if (start < end)
4     {
5         int k = Partition(data, start, end);  //分解成左右两个数组
6         QuickSortCore(data, start, k - 1);  //排序左边的数组
7         QuickSortCore(data, k + 1, end);  //排序右边的数组
8     }
9 }

  从上面的代码中可以看出,分解A数组为左右两个数组是快速排序算法的关键,这个问题本质上为:对数组A中的某个值A[k](k为数组的下标),将小于A[k]的数存放在数组A的前面,将不小于A[k]的数存放在数组A的后面,分界线为x。

  解决该问题的一种很直观的方法就是先将A[k]与A[r]交换,然后用两个下标i、j,i表示A[0~i]中的数都小于A[r],j从0~r-1遍历数组A。如果发现A[j]小于A[r],则将A[i + 1]与A[j]交换,并同时增加i和j,之所以可以这样是因为A[i + 1]要么不小于A[r],要么与A[j]相同;如果A[j]不小于M,则只递增j。最后将A[i + 1]与A[r]交换,i+1为左右数组的分界线x。

 1 int Partition(int data[], int start, int end)
 2 {
 3     int k, i, j;
 4
 5     k = GetRandom(start, end);  //通过随机函数获得数组下标
 6     Swap(data + k, data + end);  //将作为分界线的数放到最后
 7     i = start - 1;
 8     for (j = start; j < end; j++)
 9         if (data[j] < data[end])  //需要交换
10         {
11             i++;
12             Swap(data + i, data + j);
13         }
14     i++;
15     Swap(data + i, data + end);
16     return i;
17 }

  解决问题的另一个方法是先将A[k]与A[l]交换,并用一个临时变量p保存A[k],也使用两个下标i和j,分别初始化为l和r。开始用j从数组右边遍历,知道发现A[j] < p为止,将A[j]赋值给A[i],并让i加1,然后用i从数组的左边遍历,知道发现A[i] > p为止,将A[i]赋值给A[j],并让j减1,然后重新开始前面的遍历,知道i == j为止。最后将p赋值给A[i],此时i为左右数组的分界线x。

 1 int Partition(int data[], int start, int end)
 2 {
 3     int k, i, j, temp;
 4
 5     k = GetRandom(start, end);
 6     Swap(data + k, data + start);  //将基准数放到最前面
 7     temp = data[start];  //保存基准数副本
 8     i = start;
 9     j = end;
10     while (i < j)
11     {
12        //从右边开始遍历,知道遇到小于temp的
13         while (i < j && data[j] >= temp)
14             j--;
15         if (i < j)
16             data[i++] = data[j];
17        //从左边开始遍历,知道遇到大于temp的
18         while (i < j && data[i] <= temp)
19             i++;
20         if (i < j)
21             data[j--] = data[i];
22     }
23     data[i] = temp;
24     return i;
25 }

  前面两个方法中,第二个方法比第一个方法要好些,第二个方法用赋值替代了第一个方法中的交换。

  代码中的GetRandom函数是用来随机获得start到end之间的一个值,它可以用rand库函数实现。

转载于:https://www.cnblogs.com/chengxuyuancc/p/3546247.html

【重温经典算法之二】快速排序相关推荐

  1. 算法整理(二)---快速排序的两种实现方式:双边扫描和单边扫描

    首先简单谈下快速排序的特点,时间复杂度O(nLog n),最差时间复杂度O(n^2),平均时间O(nLog n).因为用到了函数栈,空间复杂度为O(lg n),最差为O(n).是一种不稳定的排序方法. ...

  2. 白话经典算法系列之六 快速排序 快速搞定

    快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用,因此很多软件公司的笔试面试,包括像腾讯,微软等知名IT公司都喜欢考这个 ...

  3. oracle快速排序法,经典算法系列之快速排序算法

    快速排序(Quicksort)是对冒泡排序的一种改进.由C. A. R. Hoare在1962年提出.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但 ...

  4. 【转载】白话经典算法系列之六 快速排序 快速搞定

    原文地址:http://blog.csdn.net/morewindows/article/details/6684558 快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经 ...

  5. 重温经典算法系列: 动态规划法

    题记: 曾经享受于算法的或新颖或优美或简洁,也曾经因领会熟知算法在一些考试.竞赛(如软考和软件开发比赛)和工作中屡试不爽,但是,近来一段时间,对于算法这种灵魂类的东东似乎少有染指,实为遗憾,非常危险: ...

  6. EasyLearn--JAVA实现32个经典算法设计(二):集束算法

    集束算法的理解上相对来说还是比较简单的,该算法不是求解最优解而是尽可能的靠近最优解的算法.当集束层级达到12层以上每个子节点不超过5个时,节点数最高可达到了30W个节点左右,而需要从此得出最优解可能用 ...

  7. 经典排序之二 快速排序 + 二路归并

    快速排序,顾名思义效率相比较其他排序方法高,它是一种交换排序 基本思路是 1:将待排序数组的中间见作为一个参考值 2:大于参考值的 放右边的数组,小于参考值的放左边的数组 3:对左右两个数组做1,2操 ...

  8. 白话经典算法之七大排序

    本篇转至白话经典算法之七大排序 MoreWindows 白话经典算法之七大排序 这是本人在研一上课时所整理的文档,包括冒泡排序,直接排序这七种常用的排序方法,这些文章不仅使我在考试中取了不 错的成绩, ...

  9. Golang实现经典算法

    Golang实现经典算法 1.快速排序 func QuickSort(nums []int,left,right int){val := nums[(left+right)/2]i,j := left ...

最新文章

  1. Shell脚本示例代码
  2. linux centos 7 安装中文字体
  3. c语言readdir函数功能,C语言readdir()函数:读取目录函数
  4. fastcgi java_FastCGI
  5. js 控制超出字数显示省略号
  6. 测试用例综合设计方法
  7. AI (1)---没错,AR其实也是AI
  8. 基于 lumen 的微服务架构实践
  9. HTML浅学入门---基础知识 (1)基本规则
  10. (04)VTK移动模型,判断是否相交
  11. Win10之广告弹窗终结器:Process Explorer
  12. plsql导出表结构到excel_PLSQL导出表结构和数据的三种方式
  13. python弹幕分析_《用python 玩转数据》项目——B站弹幕数据分析
  14. 青春岁月杂志青春岁月杂志社青春岁月编辑部2022年第11期目录
  15. 获取秒懂百科视频地址/获取百度百科视频地址
  16. 分享:DFC开发平台的设计理念
  17. 英特尔On技术创新峰会:携手开发者打造开放生态系统
  18. 「Jeremy Jordan」Notes on Machine learning Project Management Guidelines(机器学习项目管理指南)
  19. 软件项目管理附加实验一(项目调研)
  20. 卧槽!微信图标现在可以换颜色了?

热门文章

  1. 千元平板电脑排行榜_最值得买的平板电脑推荐-最佳平板电脑品牌排行榜【2020年10月】...
  2. mysql5建函数报1064错误,MySQL存储函数创建错误ERROR 1064和1327
  3. c command语言学例子,语言学第四章
  4. python解析pcap包已text格式输出_python分析pcap包
  5. return在c语言中是什么意思
  6. c语言规定在一个源程序中main函数的位置是什么?
  7. python程序调试题_关于python程序调试问题,一个文件计算的问题
  8. linq判断集合中相同元素个数_iOS开发swift语法梳理:集合Set
  9. pat 乙级 1003 我要通过!(C++)
  10. 光端机常见故障问题及其解决方案