排序算法5之快速排序
2015-12-22 20:59
363 查看
快速排序
很早就听说了快速排序的大名,然后看算法导论的相关视频也感觉讲的很有意思,现在总结一下。针对待排序数组{a1,a2……an}\{{a_1,a_2……a_n}\}快速排序可以分解为三步:寻找基准数,比较通常就是选择待排序的首项目或者中间项目;
2.根据与基准数的大小关系, 将待排序数组分成两个子序列:{b1,b2……bq−1}\{{b_1,b_2……b_{q-1}}\}和{cq+1,……cn}\{{c_{q+1},……c_n}\}。其中{b1,b2……bq−1}\{{b_1,b_2……b_{q-1}}\}均小于基准数,{cq+1,……cn}\{{c_{q+1},……c_n}\}均大于基准数,这样基准数的位置就确定了在q处。
然后利用递归对两个子序列进行排序。
下图是对步骤2的介绍,只是该图是将基准元素设置为最后一个元素,i和j的意义分别是,j作为遍历指针遍历从左往右遍历数组,i记录小于等于基准元素的位置,当j指向的元素小于等于基准元素时,就交换(i+1)和j指向的元素,同时i++。当j指向最后基准元素时,交换(i+1)和j指向元素的位置,返回i就是上面提到的q:
另外一种方法是,基准元素指向首项目,然后i和j分别指向首项目和尾项目。j先从右向左遍历,直至遇到某项目小于等于基准元素,交换i和j指向的项目大小;然后i从从左向右遍历,直至遇到某个项目大于基准元素,交换i和j指向的项目大小。当i和j相等时,停止遍历,返回i或者j就是上面提到的q。下面的code是我按照原理二写的。
#include<iostream> using namespace std; int quickSort(int* p,int start,int end) { int i=start,j=end; int tmp=p[i]; bool flag=true; while(i<j) { if(p[j]<=tmp&&flag) { p[i]=p[j]; flag=false; } if(flag) j--; if(p[i]>tmp&&(!flag)) { p[j]=p[i]; flag=true; } if(!flag) i++; } p[i]=tmp; return i; } void QuickSort(int* p,int start,int end) { if(start<end) { int index=quickSort(p,start,end); QuickSort(p,start,index-1); QuickSort(p,index+1,end); } } int main() { int data[10]={5,4,3,2,1,2,3,7,10,11}; QuickSort(data,0,9); for(int i=0;i<sizeof(data)/sizeof(data[0]);i++) cout<<"第"<<(i+1)<<"个项目:"<<data[i]<<endl; return 0; }
code可以进行优化:
int quickSort(int* p,int start,int end) { int i=start,j=end; int tmp=p[i]; bool flag=true; while(i<j) { while(i<j&&p[j]>tmp) j--; if(i<j) p[i]=p[j]; while(i<j&&p[i]<=tmp) i++; if(i<j) p[j]=p[i]; } p[i]=tmp; return i; }
下面是按照第一种原理写出来的code,感觉比第二种确实要简单一些。
void swap(int& a,int& b) { int tmp; tmp=a; a=b; b=tmp; } int quickSort(int* p,int start,int end) { int i=start-1,j=start; int tmp=p[end]; for(;j<=end;j++) if(p[j]<=tmp) swap(p[j],p[++i]); return i; }
性能分析
时间复杂度:就平均性能而言,快速排序被认为是目前最好的一种内部排序,通常快排的平均时间复杂度是Ω(nlog(n))\Omega(nlog(n)),但是若待排序数组已经排序好了,或者几乎是有序的,那么快速排序将退化为冒泡排序,时间复杂度Ω(n2)\Omega(n^2)。所以这种情况一般会先随机打乱数组或者随机选择基准元素的位置。
空间复杂度:最坏情况下,若每趟排序之后,枢轴位置均偏向子序列的一端(有序),栈的最大深度为Ω(n)\Omega(n)。如果在一趟划分之后比较分割所得两部分的长度,且先对长度短的子序列中的记录进行快速排序,则栈的最大深度可降为Ω(logn)\Omega(logn)。
快速排序是不稳定排序。
相关文章推荐
- java(9)--HTML
- 【hihoCoder】第77周《Koch Snowflake》题目分析
- Java自带的性能监测工具用法简介——jstack、jconsole、jinfo、jmap、jdb、jsta、jvisualvm
- jqeryUI 文本框自动补全
- 软解码和硬解码的区别
- hdu 1029 Ignatius and the Princess IV【stl】
- JavaEE request.getAttribute request.getParameter
- 大图片自适应居中显示,超出隐藏
- Codeforces Round #325 (Div. 2) F:(meet in the middle)
- 利用OpenGL固定流水线绘制球体
- 搜索引擎爬虫蜘蛛的useragent
- 架构师应该做些什么
- 加盐密码哈希:如何正确使用
- Linux下查看进程和线程
- 年末(2015)-开篇
- jquery插件模版
- C++ typedef用法小结 (※不能不看※)
- C++11 并发指南一(C++11 多线程初探)
- Java注解
- 改写世界的现实编辑器:Reality Editor