快速排序法事应用最广泛的排序算法之一,最佳情况下时间复杂度是 O(nlogn)。但是最坏情况下可能达到O(n^2)。说明快速排序达到最坏情况的原因。并提出改善方案并实现之。

答:

改进方案:改进选取枢轴的方法

1、选取随机数作为枢轴。

但是随机数的生成本身是一种代价,根本减少不了算法其余部分的平均运行时间。

2、使用左端,右端和中心的中值做为枢轴元。

经验得知,选取左端,右端,中心元素的中值会减少了快排大约 14%的比较。

3、每次选取数据集中的中位数做枢轴。

选取中位数的可以在 O(n)时间内完成。(证明见《算法导论(第二版) 》) P111 第九章中位数

和顺序统计学:在平均情况下,任何顺序统计量(特别是中位数)都可以在线性时间内得到。

快排的分割策略:

第一步是通过将枢轴元与最后一个元素交换使得枢轴元离开要被分割的数据段;i 从第一个

元素开始而 j 从倒数第二个元素开始。当 i 在 j 左边时,我们将 i 右移,移过那些小于枢轴

元的元素,并将 j 左移,移过那些大于枢轴元的元素。当 i 和 j 停止时,i 指向的是大元素,

j指向的是小元素。如果 i 在 j 左边,那么将这两个元素互换。 如果此时 i 和 j 已经交错即 i>j

所以不交换。此时把枢轴元与 i 所指的元素交换。

实例演示:

其他可以改进的地方(网络搜集) :

1、  快速排序在处理小规模数据时的表现不好.

这个时候可以改用插入排序。

当数据规模小于一定程度时,改用插入排序。具体小到何种规模时,采用插入排序,这个理

论上还不解,一些文章中说是 5 到 25 之间。SGI STL 中的快速排序采用的值是 10.

2、对于一个每个元素都完全相同的一个序列来讲,快速排序也会退化到 O(n^2)。

要将这种情况避免到,可以这样做:

在分区的时候,将序列分为 3 堆,一堆小于中轴元素,一堆等于中轴元素,一堆大于中轴元

素,下次递归调用快速排序的时候,只需对小于和大于中轴元素的两堆数据进行排序,中间

等于中轴元素的一堆已经放好

#include<stdio.h>

#include<stdlib.h>

//选取枢轴,将所有元素小于它的移到它的左边,大于它的移到它的右边,返回它的位置.

int partition(int A[],int low,inthigh)

{

if(A == NULL || low< 0 || high < 0 || low > high) //m>f>l

{

throw std::exception("invalidParameters!");

}

//选取枢轴位置,取首元素,中间元素和末尾元素的中值作为枢轴

int mid = low+(high -low) >> 1;

int firstElem = A[low];

int lastElem = A[high];

int midElem =A[mid];

int index = GetMiddleValue(A,low,high);//中位数的位置

//将枢轴元素放在第一个位置

if(index != low)//交换

{

int temp =A[index];

A[index]= firstElem;

A[low]= temp;

}

//定义两个标记,一个负责向后扫描,一个负责向前扫描

//向后每遇到一个比它大的就交换,向前扫描每遇到一个比它小的就交换

int x = A[low];//枢轴元素

int flagL =low;

int flagH =high;

while(flagL <flagH)

{

while(A[flagH] >= x &&flagL < flagH)//找到第一个比枢轴小的元素,放到当前flagL的位置

flagH--;

if(flagL < flagH)

A[flagL++] =A[flagH];

else

break;

while(A[flagL] <= x &&flagL < flagH)//找到第一个比枢轴大的元素,放到当前flagH的位置

flagL++;

if(flagL <flagH)

A[flagH--] =A[flagL];

else

break;

}

A[flagL]= x;

return flagL;

}

void qsort(int A[],intlow,int high)

{

if(low <high)

{

int k =partition(A,low,high);

qsort(A,low,k-1);

qsort(A,k+1,high);

}

}

int main()

{

int A[] ={0, 10, -5, 7, 8, -18, 33};

qsort(A,0,sizeof(A)/sizeof(int)-1);

for(int i=0;i<sizeof(A)/sizeof(int);i++)

printf("%d ",A[i]);

return 0;

}

//3值取中值

intGetMiddleValue(int A[],int low,int high)

{

int mid=low+(high-low)>>1;

int y1=A[low]>A[mid]?low:mid;

int y2=A[low]>A[high]?low:high;

int y3=A[mid]>A[high]?mid:high;

if (y1==y2)

{

return y3;

}

else

return A[y1]>A[y2]?y2:y1;

}

a + b + c - (a > b ? a > c ? a : c : b > c ? b : c) - (a < b ? a < c ? a : c : b < c ? b : c)

快速排序 改进快排的方法相关推荐

  1. 使用Java泛型实现快速排序(快排,Quicksort)

    原文:https://my.oschina.net/u/1382972/blog/169747 还可以参考:http://blog.csdn.net/stushan/article/details/5 ...

  2. 快速排序、快排的优化 及Java实现

    一.快速排序的思想 选取一个比较的基准,将待排序数据分为独立的两个部分,左侧都是小于或等于基准,右侧都是大于或等于基准,然后分别对左侧部分和右侧部分重复前面的过程,也就是左侧部分又选择一个基准,又分为 ...

  3. 快速排序—三路快排 vs 双基准

    快速排序被公认为是本世纪最重要的算法之一,这已经不是什么新闻了.对很多语言来说是实际系统排序,包括在Java中的Arrays.sort. 那么快速排序有什么新进展呢? 好吧,就像我刚才提到的那样(Ja ...

  4. 八大排序算法之快速排序(下篇)(快排的优化+非递归快排的实现)

    目录 一.前言 1.快速排序的实现: 快速排序的单趟排序(排升序)(快慢指针法实现):​ 2.未经优化的快排的缺陷 二.快速排序的优化 1.三数取中优化 优化思路: 2. 小区间插入排序优化 小区间插 ...

  5. Java实现快速排序(快排)

    快速排序是冒泡排序的改进版,也是最好的一种内排序,在很多面试题中都会出现,也是作为程序员必须掌握的一种排序方法. 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将 ...

  6. 手动编写快排(快速排序),实现从小到大和从大到小排序

    快排的方法类 package com.hcc.util;public class QuickSort {/*** * @param arr 存放数据的数组* @param left 需要排序的开始下标 ...

  7. python写快排_python 实现快速排序

    Python排序算法之快速排序 快速排序(quickSort) 快排的思想:首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这 ...

  8. 快排Quick Sort到底有多快?

    大师级的文章,总是能够使你更接近于事物的本质.   最近看了pongba的数学之美番外篇:快排为什么那么快.文中提到了Mackay的一篇文章(这里是译文),里面提到了使用信息论来解释快排与堆排的速度差 ...

  9. C语言实现稳定的快排

    关于这种稳定的快排的思路,请看我之前的这篇文章: <对数器&Python实现稳定快排> 下面是实现代码: #include<stdio.h> #include<s ...

最新文章

  1. Python计算机视觉:第六章 图像聚类
  2. git怎么上传文件到别人的仓库_Git将本地代码上传至远程仓库
  3. 如何识别一个指针式的时种的时间?
  4. SAP CRM One Order OB,OW和DB buffer的调用关系图
  5. DHCP服务器-配置
  6. sklearn官网-多分类问题
  7. 菜鸟教程 mysql like_MySQL LIKE 子句
  8. Confluence 6 修改警告的阈值和表现
  9. CentOS环境下,gdb调试中出现:Missing separate debuginfos, use: debuginfo-install.....的问题
  10. [系列教程] Discuz模板的制作方法
  11. 结构体中操作c语言,C语言中结构体的操作
  12. 下载速度15MB/s?网友实测度盘的这个新版本后惊了!
  13. Google Earth影像数据破解之旅
  14. 从「广义斯托克斯公式」结合「外微分公式」导出「牛顿-莱布尼茨公式」、「格林公式」、「高斯公式」、「斯托克斯公式」
  15. java字符串intern_String中intern方法的使用场景详解
  16. 网络嗅探器(影音神探) v4.63 绿色正式版
  17. win10系统bug:开机自动打开空白word文档
  18. Claus Hansen加入Entrust Datacard,担任亚太地区和日本销售副总裁
  19. 数据结构系列三---[一周leetcode刷题记录3.7-3.13]
  20. CAD图纸打印设置——使线条清晰有力

热门文章

  1. nano使用IMX477_12.3MP_Camera
  2. centos8ubuntu挂载exfat格式硬盘或者U盘
  3. three.js学习笔记 太阳眩光
  4. 敏捷 scrum_Scrum团队的敏捷度如何?
  5. Unity编辑器开发:2020更新
  6. 信息组织|网络信息组织
  7. 最值证折射定理_20160419
  8. offsetTop和scrollTop的区别
  9. 内嵌物理知识神经网络(PINN)画图总结
  10. Linux Neo4j 安装APOC插件