• 思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都要比另一部分的所有数据要小,然后再按此方法对这两部分数据分别进行快排,整个过程可以递归进行,以此达到整个数据变成有序序列。

  • 时间复杂度:最优情况O(nlgn) 最差情况O(n2)

  • 空间复杂度:O(1)

  • 稳定性: 快排是不稳定排序算法


三数取中法(不是快排,是对快排的优化):

由于每次取到的是序列的最右端的元素,取到极值的可能性是很大的,于是我们对他进行优化,每次选序列最左、最右和中间的元素,然后找出其中的中间元素,并把它和最右端的元素相交换,这样的话可以尽量避免取到最值,从而优化快排

代码实现:

 // 三数取中法// 三数取中法是对快排的一个优化,为了避免取到极值,进而导致快排性能变差
int GetMidIndex(int* array, int left, int right)
{int mid = left + (right - left) / 2;if (array[left] < array[mid]){if (array[mid] < array[right]){return mid;}else if (array[left] > array[right]){return left;}else{return right;}}else // left > mid{if (array[right] > array[left]){return left;}else if (array[mid] > array[right]){return mid;}else{return right;}}
}
快排版本

快排有很多版本,但是最终目的都是为了排序

1.先看提出快排思想的hoare版本


// 分治思想// [left, right] 左闭右闭区间
void QuickSort(Datatype* array, int left, int right)
{int mid = 0;int div = 0;Datatype key = 0;int begin = 0;int end = 0;// 解释一下这里 left 是有可能大于 right 的    边界细节 // 举个例子 如果此时序列是 1 2 3                   // 以3为基准 左边划分没有问题 重点看一下右边 // 递归往右边走的时候 left指向3后面的元素(下标为3的元素)right 指向3(下标为2)// 那么此时就找不到递归出口(就会Stack overflow)  // 所以这里递归出口的判断条件必须是 ">="  或者写成 !(left < right)if (left >= right){return;}// 这是我们的一种优化  三数取中法// 如果每次取序列最优端的那个元素 极易取到极值// 我们在序列中选择了三个数// 拿到这三个数的中间值 如果他不是最右边的元素就把他交换到最右边// 以此来提高快排的性能mid = GetMidIndex(array, left, right);if(mid != right){_swap(&array[mid], &array[right]);}key = array[right]; // 这是选的基准begin = left;end = right;// begin从前往后找第一个比基准值大的元素// end从后往前找第一个比基准值小的元素// 然后交换他们指向的元素 这样小数就在前面 大数就调到后面了 while (begin < end){// begin 找大while (begin < end && array[begin] <= key){++begin;}// end 找小while (begin < end && array[end] >= key){--end;}if (begin < end){_swap(&array[begin], &array[end]);}}// 当begin与end相遇的时候 begin这个位置记录的元素应该是大于基准值的// 将begin位置元素与序列最右边元素交换_swap(&array[begin], &array[right]);// begin记录分割边界 div之前元素都比 div之后的元素小div = begin;  // 递归排序列的左半部分QuickSort(array, left, div - 1);// 递归排序列的右半部分QuickSort(array, div + 1, right);
}

测试:


void Print(Datatype* array, int size);void TestQSort()
{Datatype array[] = { 12, 2, 5, 37, 34, 88, 3, 77, 9, 21, 37 };int size = sizeof(array) / sizeof(array[0]);Print(array, size);QuickSort(array, 0, size-1); // 因为是[left, right]Print(array, size);}int main()
{TestQSort();system("pause");return 0;
}void Print(Datatype* array, int size)
{int i = 0;for (i = 0; i < size; i++){printf("%d ", array[i]);}printf("\n");
}

测试结果:

2.挖坑法
这种方法是最容易理解的

 // 时间复杂度O(nlgn)// 空间复杂度O(1)// 快排// [ , ) 左闭右开区间// 挖坑
void QuickSort(Datatype* array, int left, int right)
{int mid = 0;int low = left;int high = right - 1;Datatype temp = 0;if (!(left < right))  // 解释一下这里 left 是有可能大于 right 的  边界细节 {                     // 举个例子 如果此时序列是 1 2 3                   return;           // 以3为基准 左边划分没有问题 重点看一下右边 }                   // 递归往右边走的时候 left指向3后面的元素(下标为3的元素)right 指向3(下标为2)// 那么此时就找不到递归出口(就会Stack overflow)  // 所以这里递归出口的判断条件必须是 ">="  或者写成 !(left < right)mid = GetMidIndex(array, left, right - 1);if(mid != right - 1){_swap(&array[mid], &array[right - 1]);}temp = array[high]; // 这是挖的第一个"坑" 把原来"坑"里的值用temp保存一份 原来的数据不会丢失 覆盖了也没啥事while (low < high){while (temp >= array[low] && low < high) // 这里有两个陷阱 一是 ">="   二是 low < high{low++;}if (low < high){array[high] = array[low]; // 填"坑"  并且low这个位置又是一个新的坑}while (temp <= array[high] && low < high){high--;}if (low < high){array[low] = array[high]; // 再填"坑"}}array[low] = temp; // 最后把最后一个"坑"填上QuickSort(array, left, low);QuickSort(array, low + 1, right);
}

接下来我们来测试一下”挖坑法“版本的快排

void Print(Datatype* array, int size);void TestQSort()
{Datatype array[] = { 12, 2, 5, 37, 34, 88, 3, 77, 9, 21, 37 };int size = sizeof(array) / sizeof(array[0]);Print(array, size);QuickSort(array, 0, size-1);Print(array, size);}int main()
{TestQSort();system("pause");return 0;
}void Print(Datatype* array, int size)
{int i = 0;for (i = 0; i < size; i++){printf("%d ", array[i]);}printf("\n");
}

测试结果:

/// 以下为 2019.12.25 修改

排序 ---- 快排(C语言)相关推荐

  1. 单链表排序----快排 归并排序

    单链表排序----快排 & 归并排序 原文:http://blog.csdn.net/u012658346/article/details/51141288 题目描述:  给定一个乱序的单链表 ...

  2. c语言 快排,C语言 快排函数

    C语言中有快排的函数,可以直接使用,见下面调用格式: qsort包含在头文件中,此函数根据你给的比较条件进行快速排序,通过指针移动实现排序.排序之后的结果仍然放在原数组中.使用qsort函数必须自己写 ...

  3. 快排 c语言,c语言的库函数之快排

    之前都是手写的快排 但是毕竟写太多快排了 是时候用一波他自己自带的快排了说实话要不是之前用了一次 stl 感觉封装好了的东西实在是太好用了 不禁又回想起当初用python 写的复杂的数据结构 简直不要 ...

  4. c语言快排过程,快速排序(快排)C语言实现

    快速排序 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:经过一趟排序将要排序的数据分割成独立的两部分,其中一部分的全部数据都比另一部分的全部数据都要小,而后再按此方法对这两部 ...

  5. 快排C语言三种实现方法(大同小异)

    快速排序C语言版(附带视频讲解) 注:3种快排的名字是我自己取的,并非专业名称 方法一(最常用的方法):左端抽轴(pivot)法 思路 && 操作: 排序准备:取左边第一位数为pivo ...

  6. c语言程序快排,C语言快排

    C语言使用快排的方式有两种,1.直接用库函数stdlib.h里的qsort函数 2.自己编写快排代码(第一种方便,第二种较为自由) qsort 的函数原型是: void qsort(void*base ...

  7. C语言手写快排算法,两个值时也可以使用哦!

    最近刷leetcode经常碰到排序问题,大家都知道排序算法中快速排序是效率很高的算法,因此快排写法是必须要掌握的哦! 解题思路 利用快排对数组进行排序. 快排:冒泡排序的改良. 快排目标:将数组从大到 ...

  8. c语言寻找大富翁,PTA 7-38 寻找大富翁(25 分)解法(C/C++)暴力快排/精准堆排 解法...

    7-38 寻找大富翁 (25分) 胡润研究院的调查显示,截至2017年底,中国个人资产超过1亿元的高净值人群达15万人.假设给出N个人的个人资产值,请快速找出资产排前M位的大富翁. 输入格式: 输入首 ...

  9. 快排堆排归排三种排序的比较

    目录 快排 堆排序 归并排序 三种排序的比较 快排 快速排序中最简单的(递归调用) 注:倒序,和 列表中有大量重复元素时,时间复杂度很大 快排例子 注:快排代码实现(类似于二叉树 递归调用) 时间复杂 ...

最新文章

  1. kotlin设置CORS跨域资源共享,java设置允许跨域,服务端如何设置 springboot中设置跨域资源共享
  2. 山西对口升学计算机分数线,2020年山西对口升学本科一批录取分数线是多少
  3. Android图表控件MPAndroidChart——曲线图LineChart的使用(财富收益图)
  4. 31岁负债59万(房贷27万,私人借款32万),该怎么办?
  5. 基于mini2440的ov9650摄像头裸机测试
  6. python socket编程_Python学习记录-socket编程
  7. 5.3linux下C语言socket网络编程简例
  8. centos7中yum源安装mysql_centos7下使用yum安装mysql
  9. 【白皮书分享】2022年私域运营趋势及创业机会.pdf(附下载链接)
  10. 以线虫为模型模拟的神经网络,让机器人无需训练即可自动避开障碍物
  11. Python学习笔记——python基础之python中for......else......的使用
  12. 人力资源管理-人际交往中的6个心理效应
  13. 多目标蚁群算法路径规划(一)-----从数据设计到毕业论文系列
  14. ctfshow-萌赛
  15. r语言做绘制精美pcoa图_R语言进行PCoA分析
  16. CCCC天梯赛 L1-079 天梯赛的善良
  17. ata高级计算机系统,ATAOffice2010年高级解题步骤.pdf
  18. 2021-06-28国外调查问卷真的赚钱吗
  19. iOS学习笔记75-NSURLSession使用实战教程
  20. 基于JAVA高考报考指南网站计算机毕业设计源码+数据库+lw文档+系统+部署

热门文章

  1. Kanban in Action 免积分下载
  2. 西瓜书第四章习题及答案
  3. vs2012中将图片放到resource中进行调用
  4. http.cn portal.php,短网址,短网址生成,短链接,网址缩短_ft12.com短网址
  5. Integrated Electrical Test Vehicle Co-designed with Microfluidics for Evaluating the Performance of
  6. ThreadLocal中优雅的数据结构如何体现农夫山泉的广告语
  7. 项目管理软件怎么选?看看中国电信天翼云的选择
  8. 房产经纪龙头居安思危孵化「贝壳」,如何用数字化解找房之痛?
  9. 七牛判断上传图片文件是否重复
  10. 解决酷比魔方iwork手写板系列TF卡以及USB3.0不识别的问题