快速排序算法
来源:互联网 发布:淘宝上hm折扣代购真假 编辑:程序博客网 时间:2024/05/18 16:54
快速排序算法最早由图灵奖获得者Tony Hoare设计出来的,他在形式化方法理论以及ALGOL60编程语言的发明中都有卓越的贡献,是上世纪最伟大的计算机科学家之一。
时间复杂度:O(n*lgn)
最坏:O(n^2)
空间复杂度:O(n*lgn)
不稳定。
要注意很多细节问题,如:
- 我们知道,快速排序的分治partition过程有两种方法,一种方法是两个指针从首尾位分别向中间扫描的方法(大多数的人和一般的教材采用的是这第二种首尾向中间扫描法,算法导论的思考题7-1,P103页),这种方式是Hoare的最原始设计思想,俗称Hoare版本,需要注意的是partition操作里面一定要从右面开始,即,while(l<h && data[h]>=pivot)h--;
XXXX;
while(l<h && data[l]<=pivot)l++;
XXXX; 的顺序结构。另外一种是上面所述的两个指针索引一前一后逐步向后扫描的方法(算法导论P95页上采用的是这种方法) - partition过程中,要注意一些边界值问题。如i、j索引的初始化,for循环中,j从数组中第一个位置到倒数第二个位置h-1处,且是当data[j]<=privot(是小于等于,非小于),然后找到了之后,i++,再交换。最后还有一次data[i+1]与data[h]的交换。最后,便是返回值的问题,返回i+1。
- 第三个要注意的方面是递归处。if(l<h),才进入递归。
主要要注意的问题就是上述三个方面。只要把握好细节,那么快速排序算法,二十几行自能搞定。
对于版本一可以引用 http://developer.51cto.com/art/201403/430986.htm 的图片,这样更容易理解。
版本一伪代码(Hoare版本)HOARE-PARTITION(A, p, r) 1 x ← A[p] 2 i ← p - 1 3 j ← r + 1 4 while TRUE 5 do repeat j ← j - 1 6 until A[j] ≤ x 7 repeat i ← i + 1 8 until A[i] ≥ x 9 if i < j10 then exchange A[i] ↔ A[j]11 else return j</strong></span>
版本二伪代码:QUICKSORT(A, p, r)1 if p < r2 then q ← PARTITION(A, p, r) //关键3 QUICKSORT(A, p, q - 1)4 QUICKSORT(A, q + 1, r)数组划分快速排序算法的关键是PARTITION过程,它对A[p..r]进行就地重排:PARTITION(A, p, r)1 x ← A[r]2 i ← p - 13 for j ← p to r - 14 do if A[j] ≤ x5 then i ← i + 16 exchange A[i] <-> A[j]7 exchange A[i + 1] <-> A[r]8 return i + 1</span></strong>
下面是实际的代码(可运行,我在code::blocks运行成功)
这几种方式在于分区操作的不同而已,其他都相同。
partition1:是原始的Hoare版本,即两个指针分别由首尾向中间进行扫描
partition1_1:是原始Hoare版本的另一版本,同理上面
partition2:是后来的改版,即两个指针索引从首部一前一后逐步向后扫描
可以将 quicksort函数中的分区操作由上面的这几种方式代替即可。
#include <iostream>#include <stdio.h>using namespace std;void swap(int* a,int* b){ int temp = *a; *a = *b; *b = temp;}int partition2(int data[],int l,int h){ int i=l-1,j; int pivot = data[h]; for(j=l;j<h;j++){ if(data[j]<=pivot){ i++; swap(&data[i],&data[j]); } } swap(&data[h],&data[i+1]); return i+1;}int partition1(int data[],int l,int h){ int pivot = data[l]; while(l<h){ while(l<h && data[h]>=pivot)h--; data[l]=data[h]; while(l<h && data[l]<=pivot)l++; data[h]=data[l]; } data[l]=pivot; return l;}int partition1_1(int data[],int l,int h){ int pivot = data[l]; while(l<h){ while(l<h && data[h]>=pivot)h--; swap(&data[l],&data[h]); while(l<h && data[l]<=pivot)l++; swap(&data[l],&data[h]); } return l;}void quicksort(int data[],int l,int h){ if(l<h){ int pivot = partition2(data,l,h); quicksort(data,l,pivot-1); quicksort(data,pivot+1,h); }}int main(){ int data[] = {87,45,12,32,56,89,98,1,34,65}; quicksort(data,0,9); for(int t=0;t<10;t++){ cout<<data[t]<<" "<<endl; } return 0;}
如果未来我看不懂代码啦,请自己去看算法导论!一定能看懂
0 0
- 排序算法--快速排序
- 排序算法--快速排序
- 排序算法---快速排序
- 排序算法-快速排序
- 排序算法------快速排序
- 排序算法---快速排序
- 排序算法-快速排序
- 排序算法---快速排序
- 排序算法--快速排序
- 排序算法--快速排序
- 排序算法--快速排序
- 排序算法:快速排序
- 排序算法 快速排序
- 排序算法--快速排序
- 排序算法--快速排序
- 【排序算法】快速排序
- 排序算法--快速排序
- 排序算法:快速排序
- 读书笔记_Effective_C++_条款三十一:将文件间的编译依存关系降至最低
- 2014阿里巴巴校招在线笔试题(数据研发工程师岗位)之二叉树
- HttpClient入门
- 数组中有一个数字出现的次数超过了数组长度的一半,请找出这个数。java实现
- C++中的智能指针问题
- 快速排序算法
- 《初学JAVA》
- 利用栈求逻辑运算表达式的真值
- scrapy
- Uva10054 无向图打印任意欧拉回路
- java 对reids的操作 切片与非切片连接池的应用
- .net新手之学习之路一
- 移动GPU通用计算现状与展望
- spark下测试akka的分布式通讯功能