快速排序的非递归实现 -- 人人网2014笔试题目

简介:

快速排序是各大公司笔试面试中出现频率最高的几个之一,因为它在实际应用中经常用到!

在看快速排序的的非递归之前我们先看看几种经典的快速排序的递归的实现。

/*
*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;
}

到此程序结束!


如果有疑问请留言交流!

目录
相关文章
AutoJs曲线滑动---贝塞尔曲线
AutoJs曲线滑动---贝塞尔曲线
489 0
|
存储 SQL 关系型数据库
OceanBase与MySQL有何区别?
【8月更文挑战第12天】OceanBase与MySQL有何区别?
3707 3
|
Docker 容器
如何解决Docker容器和宿主机时间同步问题
在使用了Docker以后,大家可能遇到的一个问题就是Docker容器的时间和宿主机时间不同步。造成这个问题的主要原因是宿主机设置了时区,而Docker容器并且设置,导致两者相差8小时。 接下来,我们通过在在宿主机和容器里分别执行date命令来看下实际的情况。 在宿主机执行date命令的结果:
34019 0
|
关系型数据库 MySQL 数据安全/隐私保护
|
弹性计算 网络协议 安全
【OSS】基于Windows的ECS实例实现OSS反向代理
阿里云OSS的存储空间(Bucket)访问地址会随机变换,您可以通过在ECS实例上配置OSS的反向代理,实现通过固定IP地址访问OSS的存储空间。
559 0
【OSS】基于Windows的ECS实例实现OSS反向代理
|
存储 缓存 编解码
视图计算背后的技术架构思考
5G时代海量视图计算场景,阿里云边缘计算节点聚焦视频上云和处理方向,阿里云高级技术专家为您解读海量视图计算背后的技术与架构能力。
1939 0
视图计算背后的技术架构思考
使用ResourceBundle实现资源的统一调配 | 带你学《Java语言高级特性》之二十八
在程序国际化的进程当中,不可避免的会出现关于资源文件的读取问题。本节将为你介绍ResourceBundle类的相关内容,助你实现资源的统一调配工作。
使用ResourceBundle实现资源的统一调配 | 带你学《Java语言高级特性》之二十八
|
前端开发
图片在固定宽高盒子中的显示问题
我们经常可能会遇到这样一个情况: 在一个固定宽高的盒子中,要放置一张宽高比不定的图片(比如说后台上传的图片),这时候图片应该如何设置样式呢? 有人可能会说,那还不简单,图片宽高设置成父级盒子的宽高不就行了? 举个例子: /*HTML*/ /*CSS*/ .
1424 0
|
Web App开发 XML JavaScript