【非递归】手搓快速排序

该篇博客介绍了如何用非递归方式实现快速排序,通过观察递归版本的快速排序逻辑,利用栈来存储待处理的区间,在循环中不断进行单趟排序和子区间调整,直到所有子区间只剩下一个元素或为空。
摘要由CSDN通过智能技术生成

欢迎来到 Claffic 的博客 💞💞💞

前言: 

快速排序已经带大家实现过了,我们用到的方法是递归法,你知道吗,用循环也可以实现快速排序,来看看吧。

注:

这篇博客属于数据结构内容,建议学习完C语言的小伙伴食用~


目录

🐯1.快排回顾

🦁2.非递归思想

🐮3.实现


1.快排回顾

还记得递归版的快速排序是怎么实现的吗? 

默认使用前后指针法:
 

代码实现:

//快排(前后指针法)
void QuickSort3(int* a, int left, int right)
{
	if (left >= right)
		return;

	//三数取中
	int midi = GetMidi(a, left, right);
	if (midi != left)
	    Swap(&a[midi], &a[left]);

	int keyi = left;
	int key = a[left];
	int prev = left;
	int cur = left + 1;

	while (cur <= right)
	{
		if (a[cur] < key && ++prev != cur)
			Swap(&a[cur], &a[prev]);
		cur++;
	}
	Swap(&a[keyi], &a[prev]);//与下标为keyi的交换
	keyi = prev;

	//递归
	QuickSort3(a, left, keyi - 1);
	QuickSort3(a, keyi + 1, right);
}

在代码末尾进行了递归操作,那么非递归如何实现呢? 

2.非递归思想

要想用非递归实现排序,我们首先要观察递归是如何实现的: 

不变的是一趟中数字的交换逻辑,

变化的是需要进行 调整的区间

我们从变化的入手:

可以看到,调整的区间在变化(紫色标号);

也就是说,我们可以在循环中 存储要调整的区间 ,用到时再取出来;

这个有先入后出的特点,可以选择栈来实现。

那么如何模拟返回条件呢?

递归版是一个数字的时候就返回,那么非递归版就可以是子区间有一个值或者没有值就不把区间入栈。

思路总结:

里面取一段区间,单趟排序;

• 单趟分割子区间入栈;

• 子区间只有一个值或者不存在就不入栈

3.实现

void QuickSortNotR(int* a, int left, int right)
{
	Stack ST;
	StackInit(&ST);
	StackPush(&ST, right); // 先入右,再入左,才能先出左,再出右。
	StackPush(&ST, left);

	while (!StackEmpty(&ST))
	{
        // 取出区间
		int begin = StackTop(&ST);
		StackPop(&ST);
		int end = StackTop(&ST);
		StackPop(&ST);

        // PartSort3返回是快速排序的keyi值
		int keyi = PartSort3(a, begin, end);
		//[begin,keyi-1] keyi [keyi+1,end]
        //满足非一零就出栈
		if (keyi + 1 < end)
		{
			StackPush(&ST, end);
			StackPush(&ST, keyi + 1);
		}
		if (begin < keyi - 1)
		{
			StackPush(&ST, keyi - 1);
			StackPush(&ST, begin);
		}
	}

	StackDestroy(&ST);
}

代码已上传至 我的gitee 

拿走不谢~


总结: 

这篇博客内容比较简单,就是仿照递归版本实现了非递归的快速排序。

码文不易 

如果你觉得这篇文章还不错并且对你有帮助,不妨支持一波哦  💗💗💗

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Claffic

赏包辣条~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值