快速排序————非递归实现

2023-11-17

二.递归实现快速排序

2.1.为什么我们要去通过递归实现我们的快速排序呢?

大家有可能会想是不是因为递归非常的占用空间,我们都知道我们的局部变量是保存在栈上的我们的函数参数也是在栈上开辟的,所以说递归是不是会占用我们非常多的栈空间,同时呢我们的递归是一个非常深的一个操作,我们往往会因为一个函数递归出来的结果而去让这个函数重复调用多次去解决我们当前的问题,我们的快速排序非递归就是这样的方式,也包括之前的一个斐波那契数列使用递归去解决都是使用了栈;这样的方法在递归的深度不大的时候不会产生什么问题但是如果我们需要去处理的数据非常多,递归的深度非常深那么我们这个时候递归真的不会出现问题吗?

举一个例子:

我们去使用递归求1+2+3+4+。。。。n;

我们从n=100  n=1000  n=1000;  来看一看会是什么样的结果

 

 

 由此可见在一些数据过大的情况下我们的递归是非常非常难进行下去的,首先他的数据越多我们的递归越深,栈的空间就越来越少,最后入不敷出我们的栈就溢出了(stack over);

现在就知道我们为什么要使用我们的的非递归来为此我们的快速排序!

2.2,使用非递归实现我们的快速排序

我们可以先通过递归的特点来想一想如何通过栈去转换?

 

1.初始化我们的栈。

2.入栈把我们的开始的left==0  right==n-1;

3.进入我们的循环体循环体进入的条件是判断栈中是否还有数值如果有数值的化什么其中的数值对应的范围还是没有序的就需要出栈(这个时候就需要进行出栈(注意栈的数值的左右范围的对应))进行我们的挖坑排序(对于挖坑我们应该把key返回出来通过key的数值进行我们再一次的入栈操作同时我们的范围)。

3.1[left   key-1] 和[key+1   right]   这样的范围满足条件才能继续push  之后pop进行我们的排序;

4如果说我们的循环体结束了的话我们的数组就一定有序!

(这里需要注意的是入栈和出栈的对应的left  和 right 不要拿错了这个时候可以自己画一画图看一看,并且当我们的范围小到自己和自己是不是就不需要push入栈去进行自己和自己的排序所以这个地方push的条件也非常重要!)

//栈的声明
#pragma once

#include<stdio.h>
#include<stdbool.h>
#include<assert.h>
#include<stdlib.h>

typedef int STDataType;

typedef struct strck
{
	STDataType* a;//数据
	int top;//栈顶
	int capacity;//容量
}ST;

//实现的的功能
//传地址才能改变
// 
//进行一个初始化
void StackInit(ST* ps);
//进行内容释放
void StackDestory(ST* ps);
//进行入数据,栈只规定在顶去push;
void StackPush(ST* ps, STDataType x);
//进行出数据,栈只规定在定去pop
void StackPop(ST* ps);
//获取栈顶的数据
STDataType StackTop(ST* ps);
//获取栈的大小
int Stacksize(ST* ps);
//判断栈是否为空
bool StackEmpty(ST* ps);


#include"strack.h"

//进行一个初始化
void StackInit(ST* ps)
{
	ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->a == NULL)//开辟空间失败
	{
		printf("realloc fail\]n");
		exit(-1);
	}
	
		ps->top = -1;
	    //ps->top = -1;
		//ps->top=0;
		ps->capacity = 4;
	
}

//进行内容释放
void StackDestory(ST* ps)
{
	assert(ps);//断言只有不是空才可以被释放
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}
//进行入数据,栈只规定在顶去push;
void StackPush(ST* ps, STDataType x)
{
	//我们的栈top==-1开始我们要++再入数据
	assert(ps);//进行判断

	//进行加空间
	if (((ps->top)+1) == (ps->capacity))//top+1 不这样的化容量是认为我们是够的但是-1,开始实际上是不够的;
	{
		STDataType* tmp = (STDataType*)realloc(ps->a,
			sizeof(STDataType) * 2*ps->capacity);
		if (tmp == NULL)//开辟空间失败
		{
			printf("realloc fail\]n");
			exit(-1);
		}
		else//开辟空间成功
		{
			ps->capacity *= 2;
			ps->a = tmp;
		} 
	}
	ps->top++;
	ps->a[ps->top] = x;
	//(ps->top)++;
	//*(ps->a + (ps->top)) = x;另一种方法


}


//进行出数据,栈只规定在定去pop
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top >= -1);
	//assert(ps->top > 0);
	//加一个条件不敢去一直--;
	ps->top--;

}
//获取栈顶的数据
STDataType StackTop(ST* ps)
{
	assert(ps);
	//assert(ps->top >= -1);
	return ps->a[ps->top];//我们的top从-1开始所以
	return ps->a[ps->top-1];

}
//获取栈的大小
int Stacksize(ST* ps)
{
	return (ps->top + 1);
	//return ps->top ;
}
//判断栈是否为空
bool StackEmpty(ST* ps)
{
	assert(ps);
	return (ps->top == -1);
	//return (ps->top == 0);
}

有一说一这个非递归实现快速排序是非常有意义他考察了我们对于栈的实现和应用能力,加入了我们快速排序的特点,这个题目的挖坑排序返回值是非常重要的,同时对于改变环境下的关于在对应情况下的是否入栈也十分重要!!!希望这篇文章可以帮助到大家!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

快速排序————非递归实现 的相关文章

随机推荐

  • numpy.random.RandomState() numpy里random总结

    numpy random RandomState 函数用法 可以通过numpy工具包生成模拟数据集 使用RandomState获得随机数生成器 from numpy random import RandomState rdm RandomS
  • nginx+fastcgi+c/c++源码安装配置

    参考 http www cnblogs com xiaouisme archive 2012 08 01 2618398 html 由于以前安装过apache 已经安装了很多依赖库 现在只需要安装以下软件包 nginx 1 4 4 tar
  • s3cmd put 时提示 ERROR: S3 error: 403 (QuotaExceeded)

    配置里的rgw配额是10000000写满 s3cmd put 时提示 ERROR S3 error 403 QuotaExceeded rgw bucket default quota max objects 值为 1 查看配额信息 rad
  • 线性模型的介绍

    一 背景 在一个理想的连续世界中 任何非线性的东西都可以被线性的东西来拟合 所以理论上线性模型可以模拟物理世界中的绝大多数现象 线性模型 Linear Model 是机器学习中应用最广泛的模型 指通过样本特征的线性组合来进行预测的模型 给定
  • 【python基础知识】12.类与对象(一)

    类与对象 一 类 的基本概念 万事万物 皆为对象 类的创建和调用 我们都是中国人 类的创建 类的调用 总结 这篇文章中 我们会接触到一种全新的编程思维 面向对象编程 Object Oriented Programming 相信这种编程思维
  • Java基础(七): instanceof用法详解

    1 instanceof说明 instanceof 是 Java 的保留关键字 作用是 测试它左边的对象是否是它右边的类的实例 返回 boolean 的数据类型 instanceof是Java中的二元运算符 左边是对象 右边是类 当对象是右
  • MySQL中的各种查询

    文章目录 MySQL中的各种查询 基础查询 条件查询 排序查询 常见函数查询 分组查询 连接查询 内连接 外连接 交叉连接 子查询 联合查询 MySQL中的各种查询 基础查询 条件查询 语法 select 查询列表 from 表名 wher
  • html 与 js

    一 1 js java script js 基于对象 解释执行 java 面向对象 编译执行 2 html 引入 js 方式 1 内部 js body的最后一行 如下 3 控制台的输入输出 1 console log 内容 4 js 变量和
  • -lz -lrt -lm -lc都是什么库

    libz librt libm libc 压缩库 Z 实时库 real time 数学库 math 标准C库 C lib
  • get it [springmvc controller 单例说明以及多例切换]

    spring的bean作用域种类 1 singleton 单例模式 当spring创建applicationContext容器的时候 spring会欲初始化所有的该作用域实例 加上lazy init就可以避免预处理 2 prototype
  • Junit单元测试

    概念 JUnit是一个 Java 编程语言的单元测试工具 可以对部分代码的进行测试 Junit是用于Java的单元测试的框架 是别人写好的 特点 JUnit是一个开放源代码的测试工具 提供注解来识别测试方法 JUnit测试可以让你编写代码更
  • npm安装vue-cli,一直停留在deprecated request@2.88.2: request has been deprecated, see https://github.com/req

    安装vue cli出现的错误 原因 资源问题 没有配置淘宝镜像 解决 配置淘宝镜像 npm config set registry https registry npm taobao org 重新安装vue cli 即可成功 npm ins
  • 多线程中sleep、yield、join的用法及sleep与wait区别

    Object中的wait notify notifyAll 可以用于线程间的通信 核心原理为借助于监视器的入口集与等待集逻辑 通过这三个方法完成线程在指定锁 监视器 上的等待与唤醒 这三个方法是以锁 监视器 为中心的通信方法 除了它们之外
  • 分析java源代码/开源框架源码的思路?

    讨论下大家分析源代码的思路 遇到源代码是怎样去分析的 我的思路基本是这样的 1 弄清楚这个框架 是做什么用的 分解功能 2 分解功能出来后 针对每个功能画出类框架图 3 找到功能入口 然后分析每个方法 有个疑惑 在分析方法的过程中 方法链会
  • 解决数组塌陷的两种方式

    解决数组塌陷的两种方式 1 i 2 将数组倒着循环遍历 转载于 https www cnblogs com oklfx p 8495060 html
  • vuex是什么?

    vuex解释 vuex是一个专门为vue js应用程序开发的状态管理模式 通俗点说就是我们项目中需要共享的一些数据的管理容器 这里的状态就是数据 那么什么情况下才应该使用vuex呢 简单的说就是当你在构建一个中大型单页用的时候 需要在组件外
  • QCombox隐藏某一项

    有事想隐藏下拉选项的某一项 而又不改变索引 可以使用如下方法 QListView view qobject cast
  • 设计模式之六大原则

    设计模式之六大原则 转载 关于设计模式的六大设计原则的资料网上很多 但是很多地方解释地都太过于笼统化 我也找了很多资料来看 发现CSDN上有几篇关于设计模式的六大原则讲述的比较通俗易懂 因此转载过来 原作者博客链接 http blog cs
  • Parallels desktop 10 虚拟机支持 USB 3.0

    自Parallels Desktop 8 0 18305 起虚拟机可支持USB 3 0 以Parallels Desktop 10 for Mac为例 如何在虚拟机启用USB 3 0 为了在虚拟机中启用 USB 3 0 请首先在配置中启用功
  • 快速排序————非递归实现

    二 递归实现快速排序 2 1 为什么我们要去通过递归实现我们的快速排序呢 大家有可能会想是不是因为递归非常的占用空间 我们都知道我们的局部变量是保存在栈上的我们的函数参数也是在栈上开辟的 所以说递归是不是会占用我们非常多的栈空间 同时呢我们