快速排序总结
来源:互联网 发布:淘宝氛围图是什么 编辑:程序博客网 时间:2024/05/18 01:41
文章总结自《编程珠玑》。
首先提一下插入排序,在后面的优化中可以用到:
最简单的插入排序:
isort1:
for i = [1, n)
for(j = i; j> 0 && x[j - 1] > x[j] ; j--)
swap(j-1, j)
优化策略:不进行转化,将要插入的数存储起来,从后往前进行查找赋值,直到遇到更小的数时,将存储起来的值赋值给更小的数的后面一位。
isort2:
for i = [1, n)
t = x[i]
for(j = i; j> 0 && x[j - 1] > t; j--)
x[j] = x[j - 1]
x[j] = t
简单的快排:
一旦发现某个元素比标准元素小了,则进行交换,平均为O(nlogn)时间以及O(logn)栈空间
void qsort1(l, u)
if(l >= u) return
m = l
for i = [l + 1, u]
if(x[i] < x[l])
swap(++m, i)
swap(l, m) // 需特别注意
qsort1(l, m - 1)
qsort1(m + 1, u)
如果从右向左进行扫描,可以省去for循环外的swap
在排序元素全都相等的情况下,会退化为平方时间的算法。
可以使用双向划分进行优化: 注意元素相等时候的处理措施:进行交换
void qsort2(l, u)
if l >= u
return
t = x[l]; i = l; j = u + 1
loop
do i++ while i <=u && x[i] < t
do j-- while x[j] > t
if i > j
break
swap(i, j)
swap(l, j)
qsort2(l, j - 1)
qsort2(j + 1, u)
另外,为了防止对于有序序列每次只移动一个元素,采取随机设置排序下标的方式,而不是只以第一个下标为基准进行排序:
swap(l, randint(l, u))
同时,当要排序的数组足够小时,可以考虑用插入排序进行处理,因为数组已经基本有序了,cutoff一般在50左右比较理想:
qsort3(0, n - 1)
isort2()
void qsort3(l, u)
if u - l < cutoff
return
swap(l, randint(l, u))
t = x[l]; i = l; j = u + 1 loop
do i++ while i <=u && x[i] < t
do j-- while x[j] > t
if i > j
break
temp = x[i]; x[i] = x[j]; x[j] = temp
swap(l, j)
qsort3(l, j - 1)
qsort4(j + 1, u)
再附上快排的递归以及非递归实现源码,并不是最优化版本,
转自http://www.cnblogs.com/zhangchaoyang/articles/2234815.html。
非递归实现时间上就是用栈保存每一个待排序子串的首尾元素下标,下一次while循环时取出这个范围,对这段子序列进行partition操作
#include<iostream>#include<vector>#include<stack>#include<cstdlib>#include<algorithm>using namespace std; /**把数组分为两部分,轴pivot左边的部分都小于轴右边的部分**/template <typename Comparable>int partition(vector<Comparable> &vec,int low,int high){ Comparable pivot=vec[low]; //任选元素作为轴,这里选首元素 while(low<high){ while(low<high && vec[high]>=pivot) high--; vec[low]=vec[high]; while(low<high && vec[low]<=pivot) low++; vec[high]=vec[low]; } //此时low==high vec[low]=pivot; return low;} /**使用递归快速排序**/template<typename Comparable>void quicksort1(vector<Comparable> &vec,int low,int high){ if(low<high){ int mid=partition(vec,low,high); quicksort1(vec,low,mid-1); quicksort1(vec,mid+1,high); }} /**使用栈的非递归快速排序**/template<typename Comparable>void quicksort2(vector<Comparable> &vec,int low,int high){ stack<int> st; if(low<high){ int mid=partition(vec,low,high); if(low<mid-1){ st.push(low); st.push(mid-1); } if(mid+1<high){ st.push(mid+1); st.push(high); } //其实就是用栈保存每一个待排序子串的首尾元素下标,下一次while循环时取出这个范围,对这段子序列进行partition操作 while(!st.empty()){ int q=st.top(); st.pop(); int p=st.top(); st.pop(); mid=partition(vec,p,q); if(p<mid-1){ st.push(p); st.push(mid-1); } if(mid+1<q){ st.push(mid+1); st.push(q); } } }} int main(){ int len=1000000; vector<int> vec; for(int i=0;i<len;i++) vec.push_back(rand()); clock_t t1=clock(); quicksort1(vec,0,len-1); clock_t t2=clock(); cout<<"recurcive "<<1.0*(t2-t1)/CLOCKS_PER_SEC<<endl; //重新打乱顺序 random_shuffle(vec.begin(),vec.end()); t1=clock(); quicksort2(vec,0,len-1); t2=clock(); cout<<"none recurcive "<<1.0*(t2-t1)/CLOCKS_PER_SEC<<endl; return 0;}
1 0
- 总结的快速排序
- 快速排序总结
- 【排序总结--插入、快速】
- 快速排序总结
- 快速排序总结_legend
- 快速排序总结
- C++快速排序总结
- 快速排序总结
- 快速排序总结
- java快速排序总结
- Java快速排序总结
- 快速排序算法总结
- 快速排序总结
- 快速排序分析总结
- qsort快速排序总结
- 快速排序法总结
- 快速排序总结
- 快速排序总结
- eclipse Could not write metadata for
- DM6446之GPIO中断
- 制作验证码时,将gd2图像处理扩展功能开启的方法
- APUE: 12-2程序清单 使用递归锁 处:能不能不用递归锁? P321
- 目标检测中背景建模方法
- 快速排序总结
- IE6下PNG交互时无效果解决方案。
- Python的设计理念和优缺点
- 编译时遇到如下错误error C2061: syntax error : identifier 'THIS_FILE'
- 循环冗余校验码(CRC)应用总结(包括C++源码)
- C语言写的扫雷
- Android项目总结
- poj 1755 Triathlon(半平面解线性规划)
- win7,python2.7.6安装pip