快速排序算法

快速排序算法,看看名字就知道它在所有的目前已知的算法是最快的,它的基本思想是“分治”,其实算法不难理解,看看代码也能明白什么意思,大一上学期就学会了这种算法,可是每次过了老长时间,就把它给忘了,最终还是要看模版。因此代码无所谓,关键是你必须理解这种思想,不是明白就行!!好吧废话多了~

C++STL模板库<algorithm>和C语言函数库<stdlib.h>都有对应的实现,我就不介绍了~但给出相应的库函数链接:

C qsort():   http://www.cplusplus.com/reference/cstdlib/qsort/?kw=qsort;

C++ sort(): http://www.cplusplus.com/reference/algorithm/sort/?kw=sort;

现在开始详细的讲解一下快速排序,分治的思想你懂么?给你1000个数,让你从小到大排序,直接排序肯定很困难,因此,如果我们从1000个数中随机选出一个数pivot,所有的数都和pivot比较,然后把所有的比pivot小的数放到pivot的左边,所有比pivot大的放到pivot的右边,这样最终我们就找了pivot的最终的位置 如下图所示

 

                  <pivot                              pivot                    >=pivot                         &nbsp;

 

那么,如何才能找到pivot的最终位置呢?一般情况下,我们选择pivot的值为要排序数组的的第一个元素或者是最后一个元素,事实上任何一个元素都可以,然后就是确定pivot在数组中正确的位置,以后都不会对其进行改动。下面说一下一种实现,我们需要一个整数索引(数组的下标)loc,loc的位置左边都是小于pivot的,loc的右边都是大于pivot的,初始化的时候 loc指向待排序序列的第一个元素。然后遍历整个序列(i = start ,i<end),如果比pivot小,就要求这个数和loc所指向的数进行交换,然后loc++,这样loc左边的肯定小于pivot。然后一次遍历之后loc的位置就是pivot的最终位置,把pivot所在位置的元素与loc指向的那个元素进行交换。然后递归~~分治 。

C++代码如下:排序元素区间[start,end)

void quick_sort(int arr[],int start,int end)
{
	if(start >= end)
		return;
	int loc = start;
	int tmp;
	for(int i = start;i < end;++i)
	{
		if(arr[i] < arr[end-1])
		{
			tmp = arr[i];
			arr[i] = arr[loc];
			arr[loc] = tmp;
			loc++;
		}
	}
	tmp = arr[end-1];
	arr[end-1] = arr[loc];
	arr[loc] = tmp;
	quick_sort(arr,start,loc);
	quick_sort(arr,loc+1,end);
}

我感觉这个是最简洁的快速排序算法,利用loc需找pivot的合适位置。。额,我这里的pivot是arr[end-1]~

 

这里还有一种实现快速排序的实现形式,我简要说一下它的实现的这种技巧。关键还是要找到pivot的正确的位置,pivot可以任选~,但是一般选择待排列的第一个元素,并且对于下面的快排你最好用首元素作为基准!如果两边找速度是不是更快呢?这里需要两个整数索引i,j 。i的左边(不包括i)是小于pivot的,j的右边肯定是大于pivot的,i初始化为start-1,j初始化为end,然后压缩区间[i,j]因为这个区间的元素与pivot的关系是不确定的,首先左边i开始i++遇到大于pivot的元素就停止,然后j--遇到第一个小于pivot的元素就停止,然后如果i<j,就把i,j所指向的元素进行交换,交换后i所指向的那个元素就小于pivot了j所指向的元素就大于pivot了,如果i>=j就退出循环,j的位置就是pivot的位置。把pivot放到j这个位置就行了~,至于为什么是j不是i下图可以说明:

假设某次交换后结果如下,明显i<j

45433447721004980

                     i        j                                     

然后我们i++ 直到i所指向的元素大于pivot,我们得到

45433447721004980

                             i

                             j

然后j--直到j所指向的元素小于pivot,我们得到

45433447721004980

                    j         i

这个时候因为j<=i了因此要退出循环 如果i指向的元素和基准交换(也就是45和47交换~~很明显错了,因为这个基准要和比它小的交换,而不是比它大的)

C++代码如下

void quick_sort(int a[],int start,int end)
{
	if(start >= end) return;
	int i = start;
	int j = end;
	int pivot = a[start];
	int tmp;
	while(true)
	{
		do {
			i++;
		}while(a[i] < pivot);
		do {
			j--;
		}while(a[j] > pivot);
		if(i >= j)
		{
			break;
		}
		tmp = a[i];
		a[i] = a[j];
		a[j] = tmp;
	}
	tmp = a[start];
	a[start] = a[j];
	a[j] = tmp;
	quick_sort(a,start,j);
	quick_sort(a,j+1,end);
}


 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值