快速排序及三种排序方法 Hoare法/挖坑法/前后指针法

快速排序

算法思想:基于分治的思想,是冒泡排序的改进型。同冒泡排序一样,快速排序也属于交换排序,通过元素之间的比较和交换位置来达到排序的目的。
不同的是,冒泡排序在每一轮只把一个元素冒泡到数列的一端,而快速排序在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边,比它小的元素移动到数列的另一边,从而把数列拆解成了两个部分。
在这里插入图片描述
每次把数列分成两部分,究竟有什么好处呢?
假如给定8个元素的数列,一般情况下冒泡排序需要比较8轮,每轮把一个元素移动到数列一端,时间复杂度是O(n^2)。

Hoare法:
在这里插入图片描述
代码

int  HoareMethod(int *a, int beain, int end)
{
	int key = a[end];
	int keyindex = end;
	while (beain < end)
	{
		while (beain < end&&a[beain] <= key)
			beain++;
		while (beain < end&&a[end] >= key)
			end--;
		swap(&a[beain], &a[end]);
	}
	swap(&a[beain], &a[keyindex]);
	return beain;
}

挖坑法:
挖坑法顾名思义,首先我们从右边先取走一个基准值用于比较的数key,取走后这个数所在的位置就成为了一个坑,然后与Hoare法类似,从左边开始找到一个比key大的数,然后将这个数填到刚在取走的数的位置,现在刚才取走的数的位置又成了一个坑,以此类推
给定原始数列如下,要求从小到大排序:
在这里插入图片描述
首先,我们选定基准元素Pivot,并记住这个位置index,这个位置相当于一个“坑”。并且设置两个指针left和right,指向数列的最左和最右两个元素:
在这里插入图片描述
接下来,从right指针开始,把指针所指向的元素和基准元素做比较。如果比pivot大,则right指针向左移动;如果比pivot小,则把right所指向的元素填入坑中。
在当前数列中,1<4,所以把1填入基准元素所在位置,也就是坑的位置。这时候,元素1本来所在的位置成为了新的坑。同时,left向右移动一位。
在这里插入图片描述
此时,left左边绿色的区域代表着小于基准元素的区域。

接下来,我们切换到left指针进行比较。如果left指向的元素小于pivot,则left指针向右移动;如果元素大于pivot,则把left指向的元素填入坑中。

在当前数列中,7>4,所以把7填入index的位置。这时候元素7本来的位置成为了新的坑。同时,right向左移动一位。
以此类推。
代码如下:

int  PitMethod(int *a, int begin,int end)
{
	int key = a[end];
	int pit = end;
	while (begin < end)
	{
		while (begin < end&&a[begin] <= key)
		{
			begin++;
		}
		a[pit] = a[begin];
		pit = begin;
		while (begin < end&&a[end] >= key)
		{
			end--;
		}
		a[pit] = a[end];
		pit = end;
	}
	a[pit] = key;
	return pit;
}

3.前后指针法
前后指针法是定义两个指针,一个cur指向数组第一个元素的位置,另一个pre指向cur的前一个位置,选取最右边的元素为key,比较cur指向的元素是否小于key,如果小于pre后移一个位置,并于cur所指向的位置的元素进行交换,然后cur后移一个位置,以此类推。
代码如下:

int PrevCurMethod(int* a, int begin, int end)
{
	int pre = begin - 1;
	int cur = begin;
	while (cur < end)
	{
		if (a[cur] < a[end] && ++pre != cur)
			swap(&a[cur], &a[pre]);
		cur++;
	}
	pre++;
	swap(&a[pre], &a[cur]);
	return pre;
}

整体快速排序:

void QuickSort(int *a, int begin, int end)
{
	if (begin >= end)
		return;
	//int keyindex = HoareMethod(a, begin, end); //Hoare法
	//int keyindex = PitMethod(a, begin, end);   //挖坑法
	int keyindex = PrevCurMethod(a, begin, end); //前后指针法
	QuickSort(a, begin, keyindex - 1);
	QuickSort(a, keyindex + 1, end);
	
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值