快速排序

快速排序:

基本原理:快速排序也是基于分治模式的。

 

分治过程的三个步骤:

分解:数组A[p...r]被划分成两个(可能空)子数组A[p..q-1]和A[q+1...r],使得A[p..q-1]中的每个元素都小于等于A(q),而且,小于等于A[q+1..r]中的元素。下标q也在这个划分过程中进行计算。

解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1...r]排序。

合并:因为两个子数组是就地排序的,将它们的合并不需要操作:整个数组A[p...r]已排序。

 

平均运行时间:O(nlgn),最坏情况运行时间为O(n^2)。

 

以上摘自《算法导论》

 

一个版本代码实现:

#include<stdio.h>


#define N 50 
int A[N] ;

int Partition(/*int *A*/int p,int r) ;
void QuickSort(/*int *A*/int p,int r) ;

int main(void)
{
	int i,n ;

	freopen("in.txt","r",stdin) ;
	while(scanf("%d",&n) != EOF)
	{
		for(i = 0 ; i < n ; ++i)
		{
			scanf("%d",&A[i]) ;
		}

		printf("You had input the List:\n") ; 
		for(i = 0 ; i < n ; ++i)
		{
			printf("%-3d",A[i]) ;	
		}
		printf("\n") ;

		QuickSort(/*A*/0,n-1) ;
		printf("After Sort:\n") ;

		for(i = 0 ; i < n ; ++i)
		{
			printf("%-3d",A[i]) ;
		}
		printf("\n\n") ;
	}
	return 0 ;
}


int Partition(/*int *A*/int p,int r) 
{
	int x = A[r] ;
	int i,j,nTemp ;
	
	i = p - 1 ;
	for(j = p ; j < r ; ++j)
	{
		if(A[j] <= x)
		{
			i++ ; 
			nTemp = A[i] ;	
			A[i] = A[j] ; 
			A[j] = nTemp ; 
		}
	}
	nTemp = A[i+1] ;
	A[i+1] = A[r] ;
	A[r] = nTemp ;

	return i+1 ;
}

void QuickSort(/*int *A*/int p,int r) 
{
	int q = 0 ;
	if(p < r)
	{
		q = Partition(p,r) ;	
		QuickSort(p,q-1) ;
		QuickSort(q+1,r) ;
	}
}



这个版本对于我来说比较好理解,特别是Partition这个函数。它将数组分为4个区间,一个是元素比主元小的区间,一个是元素比主元大的区间,一个是元素未进行与主元比较的区间,一个是主元区间。(《算法导论》有图解,更清晰)

Partition这个函数其实很好用,今天在其它地方看到两个面试题,其中一个大概就是:对一个包含正负数的数组进行处理,处理完毕之后要求全部负数在全部正数左边。时间复杂度要求O(n),空间复杂度O(1)。

思路:其实就是对0的Partition。不过,也有其它方法,之前写过,就不再提了。

另外一个面试题就是包含奇偶数的,也是要进行分开。其实也是一样的道理。

 

 

下面附上另外一个快速排序的版本,自己压根没理解:

void qsort(int lt,int rt)
{
    int i,j,mid,t;
    i = lt;
    j = rt;
    mid = a[ (lt + rt) / 2 ];
    do
    {
        while (a[i] < mid && i<rt) ++i;
        while (a[j] > mid && j>lt) --j;
        if (i<=j)
        {
            t = a[i];a[i] = a[j];a[j] = t;
            ++i;--j;
        }
    }while (i<=j);
    if (i<rt) qsort(i,rt);
    if (j>lt) qsort(lt,j);
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值