快速排序是各大公司笔试面试中出现频率最高的几个之一,因为它在实际应用中经常用到!
在看快速排序的的非递归之前我们先看看几种经典的快速排序的递归的实现。
/*
*BLOG:http://blog.csdn.net/wdzxl198
*AUTHOR:Atlas
*EMAIL:wdzxl198@163.com
*/
#include <iostream>
using namespace std;
//算法导论上的实现 ,quicksort_1
int Partition(int array[],int lhs,int rhs)
{
int x = array[rhs];
int i = lhs - 1;
for(int j=lhs;j<=rhs-1;j++)
{
if(array[j] <= x)
{
++i;
std::swap(array[i],array[j]);
}
}
std::swap(array[i+1],array[rhs]);
return i+1;
}
void quickSort_1(int array[],int lhs,int rhs)
{
while(lhs < rhs)
{
int q = Partition(array,lhs,rhs);
quickSort_1(array,lhs,q-1);
lhs = q + 1;
// quickSort(array,q+1,rhs); //消除尾递归,利用迭代控制
}
}
//编程珠玑算法
//second,quciksort_2----Simplest version, Lomuto partitioning
void quickSort_2(int a[],int lhs,int rhs)
{
if(lhs >= rhs)
return;
int m = lhs;
for(int i=lhs+1;i<=rhs;i++)
{
if(a[i] < a[lhs])
swap(a[++m],a[i]);
}
swap(a[lhs],a[m]);
quickSort_2(a,lhs,m-1);
quickSort_2(a,m+1,rhs);
}
//third,使用双向划分Two-way partitioning
void quickSort_3(int a[],int lhs,int rhs)
{
if(lhs >= rhs)
return;
int t = a[lhs],i = 1,j = rhs+1;
for(;;)
{
do
{
i++;
}while(i<=rhs && a[i] < t);
do
{
j--;
}while(a[j] > t);
if(i > j)
break;
swap(a[i],a[j]);
}
swap(a[lhs],a[j]);
quickSort_3(a,lhs,j-1);
quickSort_3(a,j+1,rhs);
}
//forth,整体使用快排划分,选取元素采用随机方法,然后基本有序后使用插入排序来进行
//qsort3 + randomization + isort small subarrays + swap inline
int randint(int l, int u)
{
return l + (RAND_MAX*rand() + rand()) % (u-l+1);
}
void isort3(int a[],int lhs,int rhs)
{
int i ,j;
for(i=lhs;i<=rhs;i++)
{
int temp = a[i];
for(
j =i;j>0 && a[j-1]>temp;j--)
{
a[j] = a[j-1];
}
a[j] = temp;
}
}
const int cutoff = 3;
void quickSort_4(int a[],int lhs,int rhs)
{
if(rhs - lhs < cutoff)
return;
int randomdata = randint(lhs,rhs);
swap(a[lhs],a[randomdata]);
int t =a[lhs],i = lhs,j = rhs + 1;
for(;;)
{
do
{
i++;
}while(i<=rhs && a[i] < t);
do
{
j--;
}while(a[j] > t);
if(i > j)
break;
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
swap(a[lhs],a[j]);
quickSort_4(a,lhs,j-1);
quickSort_4(a,j+1,rhs);
}
测试程序请读者自行设计。
总结这么几种递归的方式,可以看到是同栈结构就可以实现快速排序的非递归实现。以下就是使用STL的方法实现.
/*
*BLOG:http://blog.csdn.net/wdzxl198
*AUTHOR:Atlas
*EMAIL:wdzxl198@163.com
*/
#include<iostream>
#include<stack>
using namespace std;
int Partition(int array[],int lhs,int rhs)
{
int x = array[rhs];
int i = lhs - 1;
for(int j=lhs;j<=rhs-1;j++)
{
if(array[j] <= x)
{
++i;
std::swap(array[i],array[j]);
}
}
std::swap(array[i+1],array[rhs]);
return i+1;
}
void QuickSort(int *arr,int left,int right)
{
stack<int> st;
if(left < right)
{
int mid = Partition(arr,left,right);
if(left < mid-1)
{
st.push(left);
st.push(mid-1);
}
if(mid+1 < right)
{
st.push(mid+1);
st.push(right);
}
while(!st.empty())
{
int q = st.top();
st.pop();
int p = st.top();
st.pop();
mid = Partition(arr,p,q);
if(p < mid-1)
{
st.push(p);
st.push(mid-1);
}
if(mid+1 < q)
{
st.push(mid+1);
st.push(q);
}
}
}
else
return;
}
int main()
{
int a[10] ={3,7,6,4,0,2,9,8,1,5};
for(int i=0;i<10;i++)
cout<<a[i]<<" ";
cout<<endl;
cout<<"快速排序:";
QuickSort(a,0,9);
for(int i=0;i<10;i++)
cout<<a[i]<<" ";
cout<<endl;
system("PAUSE");
return 0;
}
到此程序结束!
如果有疑问请留言交流!