快速排序是一个分治过程:

对于数组A[p….r]选取A中的一个元素A(q),按照大小将A分成两部分 A[p…q-1] 和 A[q….r]

其中 A[p…q-1] 中所有的元素都小于A(q),而 A[q….r]中所有元素都大于 A(q).

对于划分后的数组依然采用同样的方法分裂。注意分裂后的数组可以为空,如此进行下去直到

分裂后的元素不超过一个,这将所有的小数组合并在一起就是排好序的。

递归算法如下:

quicksort(A,p,r)

if p<r

then q=partition(A,p,r)

quicksort(A,p,q-1)

quicksort(A,q,r)

算法的关键是对数组的分裂,下面用图示显示分裂过程

不妨取选取A的最后一个元素为比较元素A(q)=A[r]

用 p 记录起点,r 记录终点,j 记录当前还未做比较的起点位置,i 记录当前做完比较的分界点,即小数组的最后一个位置

(1) 比较A[j]和A[r]的大小,

如果A[j]<=A[r] 则交换A[j]和A[i+1],j++,i++    (A[j]在小数组位置)

否则,j++, (A[j]在大数组位置)

(2) 当 j = r 时,说明所有点都以比较,此时交换 A[i+1] 和 A[r] ,返回 i +1 即可

如果数组本身已经按照从小到大排好了序,可以想见其算法复杂度很高,这是最坏的情况,

这相当于每两个元素之间都要相比较,则复杂度是

\sum_{ i=1 }^n ( n-i ) = n(n-1)/2 = O(n^2) 很大 (堆排序是 O(nlogn))

最好的情况是每次都二分,算法复杂度是

T(n) = 2T(n/2) + O(n)

不妨令 n=2^k,  O(n)=Cn,  C为常数

则T(n) = 2T(2^{k-1})+Cn = 2( 2T(2^{k-2})+Cn/2)+Cn = 2^2T(2^{k-2})+2Cn

=………=2^k T(1)+Ckn = nT(1)+Cnlogn = O(nlogn) .

算法的复杂度当然是每次划分的程度有关,希望大小子树比例接近与1:1.

下面使用随机化的快速排序算法,其期望复杂度是 O(nlogn) 还是不错的:

// quicksort.cpp : 定义控制台应用程序的入口点。
//
//此程序为快速排序算法和随机化版本,原理是每次将向量分成大小两堆
//2011/3/25 肖成
#include <vector>
#include <iostream>
using namespace std;
#define N 20template<class T>
int partition(vector<T>& A, int p, int r);template<class T>
void quicksort(vector<T>& A, int p, int r);template<class T>
int random_partition(vector<T>& A, int p, int r);template<class T>
void random_quicksort(vector<T>& A, int p, int r);int main()
{double a[]={2,4,3,5,8,7,9,0,11,15,23,32,12,16.4,32,23,2.8,1,42,6,8};cout<<"The original vector is :"<<endl;for(int i=0;i<N+1;i++)cout<<a[i]<<"  ";cout<<endl;cout<<"-----------------------------------------------------------------------------------"<<endl;vector<double> vec(a,a+N+1);vector<double>::iterator iter;cout<<"quicksort"<<endl;cout<<"-----------------------------------------------------------------------------------"<<endl;quicksort(vec,0,N);for(iter=vec.begin();iter!=vec.end();iter++)cout<<*iter<<"  ";cout<<endl;cout<<"random_quicksort"<<endl;cout<<"-----------------------------------------------------------------------------------"<<endl; vector<double> vecrand(a,a+N+1);random_quicksort(vecrand,0,N);  for(iter=vecrand.begin();iter!=vecrand.end();iter++)cout<<*iter<<"  ";cout<<endl;return 0;
}template<class T>
int partition(vector<T>& A, int p, int r)
{T x=A[r];int i=p-1;for(int j=p;j<=r-1;j++){if(A[j]<=x){i=i+1;T temp=A[i];A[i]=A[j];A[j]=temp;}}A[r]=A[i+1];A[i+1]=x;return i+1;
}template<class T>
void quicksort(vector<T>& A, int p, int r)
{if(p<r){int q=partition(A,p,r);quicksort(A,p,q-1);quicksort(A,q+1,r);}
}template<class T>
int random_partition(vector<T>& A, int p, int r)
{int i=rand()%(r-p)+p;T temp=A[r];A[r]=A[i];A[i]=temp;return partition(A,p,r);
}template<class T>
void random_quicksort(vector<T>& A, int p, int r)
{if(p<r){int q=random_partition(A,p,r);random_quicksort(A,p,q-1);random_quicksort(A,q+1,r);}
}

其运行结果如下

转载于:https://www.cnblogs.com/xiao-cheng/archive/2011/10/05/2199190.html

排序算法(快速排序)相关推荐

  1. 排序算法 | 快速排序,算法的图解、实现、复杂度和稳定性分析与优化

    今天讲解一下快速排序算法的原理以及实现.复杂度和稳定性分析与优化 目录 1 快速排序的原理 2 快速排序代码实现 3 复杂度和稳定性分析.优化 4 习题练习 1 快速排序的原理 快速排序是所有内部排序 ...

  2. 排序算法 快速排序 python 0913

    排序算法 快速排序 python 0913 快速排序 思路 定义快排方法 接收参数:原始列表,起始位置,终止位置 判断是否符合快排条件,当起始下标与终止下标相等时,代表只有一个元素,无法排序,退出 一 ...

  3. 排序算法 快速排序【详细步骤图解】

    排序算法 快速排序[详细步骤图解] 快速排序 主要思想 图解 第一轮分割序列 第二轮分割序列 --- 左子序列 小结 第三轮分割序列 --- 右子序列 C++实现 总结 快速排序 给定一个序列:22 ...

  4. 【图解算法】排序算法——快速排序

    简介 首先还是得简单的介绍一下快速排序这个算法. 快速排序(Quicksort),又称划分交换排序(partition-exchange sort),一种排序算法,最早由东尼·霍尔提出.在平均状况下, ...

  5. JavaScript的排序算法——快速排序

    排序算法(Sorting algorithm)是计算机科学最古老.最基本的课题之一.要想成为合格的程序员,就必须理解和掌握各种排序算法. 快速排序(Quicksort)是对冒泡排序的一种改进. 快速排 ...

  6. 十大经典排序算法-快速排序算法详解

    十大经典排序算法 十大经典排序算法-冒泡排序算法详解 十大经典排序算法-选择排序算法详解 十大经典排序算法-插入排序算法详解 十大经典排序算法-希尔排序算法详解 十大经典排序算法-快速排序算法详解 十 ...

  7. 排序算法---快速排序(java版)

    快速排序 原理 快速排序(Quick Sort)算法,简称快排,利用的也是分治的思想,快排的思路是:如果要对 m->n 之间的数列进行排序,我们选择 m->n 之间的任意一个元素数据作为分 ...

  8. 实现快速排序的算法_排序算法-快速排序

    快速排序是由东尼霍尔所发展的一种排序算法.在平均n个项目要Ο(nlogn) 次比较.在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见.事实上,快速排序通常明显比其他 Ο(nlogn) 算法更 ...

  9. 排序算法 —— 快速排序

    快速排序算法介绍 划分问题:把数组的各个元素重排后分成左右两个部分,使得左边任意元素都小于或等于右边任意元素. 递归求解:把左右两部分分别排序. 快速排序代码 #include <iostrea ...

  10. 排序算法--快速排序

    快速排序:快速排序(Quicksort)是对冒泡排序的一种改进.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部 ...

最新文章

  1. C#基础-类成员(Day7)
  2. ValueAnimation 原理分析
  3. Qt中的QWidget
  4. shell脚本常用命令
  5. PHP微信支付没有收到微信的回调怎么修改订单状态:主动查询
  6. asp.net mvc项目实例_降龙-第13章:MVC开发准备
  7. oracle opatch那个回退,下面是我在打OPatch时使用的一般步骤,供大家参考
  8. linux tomcal 看日志,cal命令 – 显示日历
  9. 全球Top 1000计算机科学家h指数公布,中国顶尖计算机科学家人数进入前三
  10. HDU2047 阿牛的EOF牛肉串【递推】
  11. 数据库对象之存储过程
  12. (一)HBase基础介绍
  13. OBjectve-c 基本数据类型 总结
  14. 一劳永逸地激活NOD32,从此不需要NOD32激活码
  15. 1.2 数列和收敛数列
  16. 012关于指北方位惯导系统公式推导-附朱家海教授《惯性导航》
  17. 腾讯云服务器安全吗?来说说
  18. 向量ab怎么用计算机打出来,向量怎么用wps打出来
  19. 安慕希酸奶推出草莓味了
  20. Quixel bridge桥接设置

热门文章

  1. 查看进程状态信息命令 jps - (Java Virtual Machine Process Status Tool)
  2. 最长回文串--动态规划
  3. 服务器3个w目录文件夹,第 4 章 目录服务器条目 (Sun Java System Directory Server Enterprise Edition 6.2 管理指南)...
  4. alm系统的使用流程_840D sl系统授权管理
  5. win7远程桌面连接_Windows10远程桌面使用方法
  6. oracle快速备份全库,做了两次rman 全库备份,如何快速删除第一次的备份?
  7. Oracle使用imp/exp导入/导出数据库
  8. 【转】自然语言系列学习之表示学习与知识获取(三)知识图谱
  9. matplotlib可视化必知必会富文本绘制方法
  10. 记一次 Python Web 接口优化