开发者社区> tengweitw> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

【算法导论】快速排序

简介: 快速排序         快速排序的最坏运行时间为O(n2),虽然这最坏情况的时间复杂度比较大,但快速排序通常是用于排序的最佳实用选择,这是因为其平均性能相当好,平均时间复杂度为O(nlogn),并且O(nlogn)中的隐含常数因子很小。
+关注继续查看

快速排序

        快速排序的最坏运行时间为O(n2),虽然这最坏情况的时间复杂度比较大,但快速排序通常是用于排序的最佳实用选择,这是因为其平均性能相当好,平均时间复杂度为O(nlogn),并且O(nlogn)中的隐含常数因子很小。另外,它能够进行就地排序,因此在虚拟内存中也能较好的运行。

        快速排序算法的性能:其运行时间与划分是否对称有关,而是否对称与主元的选取有关。从渐进的意义上讲,如果对称,就和合并的算法一样快,如果不对称,就和插入排序算法一样慢。需要注意的是,但每次递归是都是按照常数比例划分时,从渐进意义上看,与对称划分效果一样,都是nlgn.

        和合并排序一样,快速排序也是基于分治模式的。分治过程分为三个步骤:分解、解决、合并。

        快速合并的基本思想:从要排序的序列中,随意取一个值作为主元,从而将序列以此分为大于和小于主元的两个子序列,然后重复上述过程(递归调用)。

下面以一个分解过程为例:

        假设要排序的序列为:2、8、7、1、3、5、6、4。首先,随便选取主元,在这里我们选择4;其次,通过分解将原序列分为子序列2、1、3和子序列7、5、6、8;最后分别以两个子序列为原序列,不断重复上述过程。分解过程的图解如下:



  具体实现如下:

  • 分解过程:
    /**************************************************\
    函数功能:将原数组分成全大于和全小于x的两个子数组
    输入:原始数组、要对数组进行操作的起始和结束下标
    输出:x在数组中的位置
    \**************************************************/
    
    int Partition(int*Array,int n,int p,int r)
    {
    	int x=Array[r];
    	int i=p-1;
    	int temp=0;
    	for(int j=p;j<=r-1;j++)
    	{
    		if(Array[j]<=x)
    		{
    			i++;
    			temp=Array[i];
    			Array[i]=Array[j];
    			Array[j]=temp;
    		}
    	}
    	temp=Array[i+1];
    	Array[i+1]=Array[r];
    	Array[r]=temp;
    
    	return i+1;
    }

  • 递归过程:

    /**************************************************\
    函数功能:递归调用分解函数,进行快速排序
    输入:原始数组、要对数组进行操作的起始和结束下标
    输出:无
    \**************************************************/
    
    void QuickSort(int* Array,int n,int p,int r)
    {
    	int q=0;
    	if(p<r)
    	{
    		q=Partition(Array,n,p,r);
    		QuickSort(Array,n,p,q-1);
    		QuickSort(Array,n,q+1,r);
    	}
    }


    完整实例:

    #include<stdio.h>
    
    int Partition(int*Array,int n,int p,int r);
    void QuickSort(int* Array,int n,int p,int r);
    
    void main()
    {
    	int Array[8]={2,8,7,1,3,5,6,4};
    	int n=sizeof(Array)/sizeof(int);
    	int p=0;
    	int r=n-1;
    	QuickSort(Array,n,p,r);
    
    	for(int k=0;k<n;k++)
    		printf("%d ",Array[k]);
    	printf("\n");
    }
    
    /**************************************************\
    函数功能:将原数组分成全大于和全小于x的两个子数组
    输入:原始数组、要对数组进行操作的起始和结束下标
    输出:x在数组中的位置
    \**************************************************/
    
    int Partition(int*Array,int n,int p,int r)
    {
    	int x=Array[r];
    	int i=p-1;
    	int temp=0;
    	for(int j=p;j<=r-1;j++)
    	{
    		if(Array[j]<=x)
    		{
    			i++;
    			temp=Array[i];
    			Array[i]=Array[j];
    			Array[j]=temp;
    		}
    	}
    	temp=Array[i+1];
    	Array[i+1]=Array[r];
    	Array[r]=temp;
    
    	return i+1;
    }
    
    /**************************************************\
    函数功能:递归调用分解函数,进行快速排序
    输入:原始数组、要对数组进行操作的起始和结束下标
    输出:无
    \**************************************************/
    
    void QuickSort(int* Array,int n,int p,int r)
    {
    	int q=0;
    	if(p<r)
    	{
    		q=Partition(Array,n,p,r);
    		QuickSort(Array,n,p,q-1);
    		QuickSort(Array,n,q+1,r);
    	}
    }

    注意:我是在vs2008上运行的,与vc 6.0有点区别,主要是循环体中的循环变量的作用域,出错体现在循环变量的重复定义上。例如:在vs2008或vs2010上,程序为:

    #include<stdio.h>
    void main()
    {
    int i=0;
    for(int i=0;i<5;i++)
    printf("%d ",i);
    }

    则在VC 6.0上需改为:

    #include<stdio.h>
    void main()
    {
    int i=0;
    for(i=0;i<5;i++)
    printf("%d ",i);
    } 



    原文:http://blog.csdn.net/tengweitw/article/details/9627659

    作者:nineheadedbird


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【算法导论】归并排序
1. 分治法:分治模型在每层递归的时都有三个步骤:   a.分解原问题为若干个子问题,这些子问题是原问题的规模较小的实例;   b. 解决这些子问题,递归地求解各子问题的规模足够小,则直接求解;   c. 合并这些子问题的解 成 原问题的解。
1234 0
【算法导论】插入排序
没办法就是这么没原则,又开了个坑。每天看点书,不管什么书。 1. 需求:   输入:n个数的一个序列(a1, a2,  a3……an)   输出: 输出序列的一个排列(a1', a2', a3' ……an'),满足a1'
961 0
《算法导论(原书第3版)》一2.1 插入排序
本节书摘来自华章出版社《算法导论(原书第3版)》一 书中的第2章,第2.1节,作者:(美)Thomas H.Cormen,Charles E.Leiserson,Ronald L.Rivest,Clifford Stein,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1089 0
【算法导论】排序算法总结
排序算法总结         从六月初开始看算法导论,陆陆续续看了有2个月了,但实际看的时间只有半个月左右。这期间都忙着找导师、期末考试,同时还回家修养了十来天。
1109 0
【算法导论】基数排序
基数排序 时间复杂度:O(n). 基本思路:两个数比较大小,我们的直观感觉是先比较高位,若相同则比较低位。但是这样做需要记录额外的数据,浪费空间。
644 0
【算法导论】堆排序
        堆排序像合并排序一样,时间复杂度为O(nlogn);像插入排序一样,是一种原地排序(在任何时候只有常数个元素存储在数组外)。         二叉堆的概念:是一种数组对象,可以被视为一棵完全二叉树,树的每一层都是填满的,最后一层可能除外。
763 0
【算法导论】插入排序法
插入排序法的时间复杂度为n的平方,对于较小的输入规模来说,插入排序法比合并排序法更快些。在最佳情况下,即输入数组已经排序好,则时间复杂度可表示为n,是一个线性函数;在最差情况下,即输入数组是逆序排列时,时间复杂度为.
750 0
+关注
tengweitw
所在学校:西电 兴趣爱好:编程、英语,象棋,乒乓球 email:771257840@qq.com
文章
问答
文章排行榜
最热
最新
相关电子书
更多
面试常考算法
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载