详解快速排序(递归)和非递归

目录

快排递归

快速排序hoareba版(左右指针法)

思路:

注意 

单趟实现代码

 多趟(递归)

快速排序挖坑法

思路

 单趟实现代码

 多趟(递归)

 快速排序前后指针法

思路

​单趟实现代码

 多趟(递归)​

 非递归

 栈的实现

 非递归代码实现

极端情况下的快排及优化

 优化

三数取中代码

小区间优化


快排递归

快速排序hoareba版(左右指针法)

思路:

 

注意 

 左边做key,可以让左边先走吗?

不可以

左边做key必须让右边先走,右边(right)是找比key小的,找到小的停下来,即使相遇也能保证right位置的值小于key的

单趟实现代码

基于上面的思路可以先实现hoare的单趟排序

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
//快排hoare版 单趟
void QuickSort(int* a,int begin ,int end){

	//选左边做Key ,让右边先走
	int Key = left;
	while (left < right)
	{
		//right可能越界 当为1,2,3,4,5……10,right可能越界
		//找小
		while (left < right && a[right] >= a[Key])
		{
			right--;
		}
		//找大
		while (left < right && a[left] <= a[Key])
		{
			left++;
		}
       //找到后交换
		Swap(&a[left],&a[right]);
	}
  //相遇后交换key位置的值
	Swap(&a[left], &a[Key]);
}

 多趟(递归)

单趟排序后可以得到如下结果,然后在继续重复(递归)单趟排序

 直到只有一个(数)区间就停止递归

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

//快排递归
void QuickSort(int* a,int begin ,int end){
  //递归结束的条件
	if (begin >= end)
		return;
	int left = begin, right = end;
	//选左边做Key ,让右边先走
	int Key = left;
	while (left < right)
	{
		//right可能越界 当为1,2,3,4,5……10,right可能越界
		//找小
		while (left < right && a[right] >= a[Key])
		{
			right--;
		}
		//找大
		while (left < right && a[left] <= a[Key])
		{
			left++;
		}
		Swap(&a[left],&a[right]);
	}
	Swap(&a[left], &a[Key]);

	//找到相遇的
	//int meeti = left;
    //在递归这两个区间
	//[begin,metti-1] metti [metti+1,end]
	QuickSort(a,begin,left-1);
	QuickSort(a,left+1,end);
}

快速排序挖坑法

思路

 

 单趟实现代码

void QuickSort(int* a, int left, int right)
{
	int Hole = a[left];
	while (left < right)
	{
		//找小
		while (left < right && a[right] >= Hole)
			right--;
		//找到后把right的值放到坑里,左边成为新的坑
		a[left] = a[right];
		//找大
		while (left < right && a[left] <= Hole)
			left++;
		//找到后把left的值放到坑里,右边成为新的坑
		a[right] = a[left];
	}
	//相遇后填坑
	 a[left] = Hole;
}

 多趟(递归)

和前面Hoare递归非常类似 递归左边和右边

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值