当前位置: 首页 > news >正文

排序--快排--非递归法

一,引言

快排不管是hoare法还是指针法以及挖坑法,最终都是利用函数递归进行实现的,但是只要是函数递归就会有栈溢出的风险,为此本篇文章讲解快排的非递归法。

二,代码逻辑

首先要了解为什么会使用递归进行调用,递归调用将大问题进行细分,细分成相同的小问题,依次往复,而对于快排来说,每次的单趟排序的逻辑都是一致的,不一致的仅仅的传入的参数有所不同,为此我们要思考可不可以通过一个数据结构去记录需要的两个参数,需要用到的时候取出来,之后将新的参数再次存进去。进而来依次循环,变相来实现递归的效果。

为此进行引用数据结构----栈,通过栈来存储需要的数据。下面举个例子:

这是零到九,十个数据,假设每次单趟排序经过调整后key都是中间位置。

第一次分组:[0-----4],[5],[6-------9]

如果是递归的逻辑[0------4],[6-------9]分别进行递归函数,但是如果想要走循环就需要将0和4,6和9存起来。如图:

第一次将0和9取出进行如上分组:之后继续进行存储如图:

第二次分组:将0和4取出经行单趟排序:key==2分成[0----1]和[3------4]两组继续存储:
如图:

第三次分组:将0和1取出进行单趟排序:key==0分成[0-----0],[1------1]因为只有一个数据已经是有序的,所以不进行进行存储。

第四次分组:将3和4取出依次类推,直到栈空间为空,则循环结束,排序结束。 

三,代码实现

void QuickSortNo_Re(int* p, int left, int right)
{
	Stack* m = (Stack*)malloc(sizeof(Stack));
	StackInit(m);
	StackPush(m, right);
	StackPush(m, left);
	while (StackEmpty(m) == 0)
	{
		
		
		int begin = StackTop(m);
		StackPop(m);
		int begin1 = begin;
		int end = StackTop(m);
		int end1 = end;
		StackPop(m);
		
		int keys = begin;

		while (begin != end)
		{
			while ((p[keys] <= p[end]) && begin != end)
			{
				end--;
			}
			while ((p[keys] >= p[begin]) && begin != end)
			{
				begin++;
			}
			swap(&p[begin], &p[end]);
		}
		swap(&p[begin], &p[keys]);
		keys = begin;
		if (end1 > keys + 1)
		{
			StackPush(m, end1);
			StackPush(m, keys + 1);
		}
		if (begin1 < keys-1)
		{
			
			StackPush(m, keys - 1);
			StackPush(m, begin1);
		}
		
	}
}

代码有点长,这里具体解释一下:

这里面的栈的所有引用在栈一章中都有讲解,这里的单趟排序和hoare法一致。需要注意几个点:
1,注意栈是后进先出的数据结构,所以说先进行数组尾部的入栈之后再是数据头部的入栈。 

2,当获取栈顶数据时,要记得获取一个数据后进行Pop操作,以防止获取同一个数据。

3,要多加两个变量进行标记,每次进行这个数据段的头和尾,遗忘之再排序过程中会出现丢失现象。

4,在进行判断是否入栈操作时要记得进行分别判断,具体出两段数据段是不一致的。

四,总结

快排作为非常具有实践意义的算法,熟练掌握各种方法是很重要,希望同学们多加练习都能熟练掌握。

相关文章:

  • CSS3学习教程,从入门到精通,CSS3 元素的浮动与定位语法知识点及案例代码(17)
  • nuxt3 seo优化
  • WPF中的Adorner基础用法详解与实例
  • Java中清空集合列表元素有哪些方式
  • 【Elasticsearch基础】基本核心概念介绍
  • [python]基于yolov8实现热力图可视化支持图像视频和摄像头检测
  • kubernet在prometheus+alertmanager+grafana框架下新增部署loki模块
  • 【进阶】vscode 中使用 cmake 编译调试 C++ 工程
  • uni-app页面怎么设计更美观
  • 快速入手-基于Django-rest-framework的ModelSerializer模型序列化器(三)
  • 基于模糊PID算法的智能洗衣机控制器设计,实现洗衣过程智能化,能够监测衣物重量和污泥,实现洗涤时间、洗衣液投放的智能控制
  • 解析 ID 数组传参的解决方案:基于 Axios 的实现
  • leetcode40-组合总和II
  • Linux下的socket演示程序3(udp)
  • C++调用Openssl 报OPENSSL_Uplink(503EE220,08): no OPENSSL_Applink
  • CentOS 8 Stream 配置在线yum源参考 —— 筑梦之路
  • 力扣DAY30 | 热100 | 两两交换链表中的节点
  • LeetCode hot 100 每日一题(17)——160.相交链表
  • 算法--动态规划
  • 给聊天机器人装“短期记忆“:Flask版实现指南
  • wordpress 设置版权/seo优化代理
  • 可以免费做演播的听书网站/cba最新排名
  • h5做网站用什么框架/网络广告推广服务
  • 百度网站名称和网址/一份完整的市场调查方案
  • 沈阳做企业网站的公司/2023年6月份疫情严重吗
  • 网站建设实习小结/手机端搜索引擎排名