快排非递归与计数排序

 

感谢大佬的光临各位,希望和大家一起进步,望得到你的三连,互三支持,一起进步

个人主页:LaNzikinh-CSDN博客

收入专栏:初阶数据结构_LaNzikinh篮子的博客-CSDN博客

文章目录

  • 前言
  • 一.快速排序非递归
  • 二.数据结构栈与内存栈
  • 三.计数排序
  • 四.稳定性
  • 总结

前言

计算机在实现递归时会调用系统的堆栈,这很消耗计算机内存资源,所以采用非递归算法的本质就是手动模拟系统的堆栈调用来降低computer资源的消耗,有时候还会造成栈溢出所以这些厉害的排序我们都要掌握他的非递归,然后在在补充一个计数排序。


一.快速排序非递归

递归改非递归有两种改法,一种是改循环,还有一种就是通过数据结构来转换,我们之前的归并排序非递归就是通过改循环,这次就是通过栈,去搭建

思路:先搭建一个栈,利用栈的特点,后进先出,先入右,在入左若左右存在有序,则有序不排

#include<stdio.h>
void QuickSortNonR(int* a, int n)
{
	//创建栈,初始化一个栈
	ST st;
	stackInit(&st);
	//先入右,在入左
	stackPush(&st, n - 1);
	stackPush(&st,0);
	//检查栈里还有没有元素
	while (!stackEmpty(&st))
	{
		//拿左边的值,因为是先入右,在入左,所以可以拿到
		int left = stackTop(&st);
		stackPop(&st);
		int right= stackTop(&st);
		stackPop(&st);
		//进行一次快排
		int keyIndex = Quick1sort(a, left, right);
		//如果中间右边的数小于最右,就继续入栈
		if (keyIndex + 1 < right)
		{
			stackPush(&st, right);
			stackPush(&st, keyIndex + 1);
		}
		//同理
		if (left < keyIndex - 1)
		{
			stackPush(&st, keyIndex - 1);
			stackPush(&st, left);
		}
	}
	//最后销毁栈
	stackDestory(&st);
}

这样利用数据结构搭建,大的减少了栈空间的利用,减少了大量的函数调用,不会栈溢出

二.数据结构栈与内存栈

很多人不理解,这个栈溢出和数据结构里我们写的栈有什么区别,一个是栈区,一个是数据结构线性表,这两个不是一个东西,计算机内存分为四个区域,代码区,静态区,栈区和堆区

 

  1. 代码区:存放函数体的二进制代码,由操作系统管理创建,代码区时共享的,对于频繁被执行的程序,只需要存有一份代码即可;
  2. 静态区:存放全局变量和静态变量以及常量,在程序结束后由操作系统释放;
  3. 栈区:由编译其自动分配释放,存放函数的参数值以及局部变量等;
  4. 堆区:一般由程序员通过 new 开辟空间,进行分配和释放,若程序员不释放,则程序结束时由操作系统回收通俗一点就是,栈区就是函数和函数调用,堆区就是动态开辟,栈区内容小,堆区内容大

所以多次开辟内存是可以的,但是要记得释放,但是多次函数调用会让栈的空间满,之后就溢出了,没有栈的空间了

而数据结构的栈它就是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表,特点是后进先出

所以这两个不是一个东西,不用搞混了

三.计数排序

计数排序顾名思义,就是通过计数来排序的一种排序算法,他和我们之前的算法不一样,计数排序是一种非比较排序算法,适用于整数或有限范围内的非负整数排序,它的基本思想是统计数组中每个元素出现的次数,然后根据出现次数重新构造有序序列。

思路:计数排序使用一个额外的数组,来记录次数,把带排序的数字统计到额外数组中去,最后用额外数组来反映顺序

但是有缺陷,如果我是从100开始的5个数字,101,102,...105,难道我要开辟105个空间吗?

我们之前这种思路是求的绝对映射位置,我们现在要相对的映射位置,这样才能节省空间用

最大的减最小的加1来开辟范围

	int range = max - min + 1;
	int* count = (int*)malloc(sizeof(int) * range);
	memset(count, 0, sizeof(int) * range);

开辟范围来计数,用memset来初始化,当然直接用calloc函数也是可以的

总代码思路:求出最大最小值,利用最大与最小值,开辟空间,遍历一遍,统计次数,利用次数得出顺序

#include<stdio.h>
#include<stdlib.h>
void CountSort(int* a, int n)
{
	//求出最大最小值
	int max = a[0], min = a[0];
	for (int i = 0; i < n; i++)
	{
		if (a[i] > max)
		{
			max = a[i];
		}
		if (a[i] < min)
		{
			min = a[i];
		}
	}
	//利用最大与最小值,开辟空间
	int range = max - min + 1;
	int* count = (int*)malloc(sizeof(int) * range);
	memset(count, 0, sizeof(int) * range);
	//遍历一遍,统计次数
	for (int i = 0; i < n; i++)
	{
		//注意要减去最小值
		count[a[i] - min]++;
	}
	int j = 0;
	for (int i = 0; i < range; i++)
	{
		while (count[i]--)
		{
			//前面减了现在要加上
			a[j] = i + min;
			j++;
		}
	}
	free(count);
}

计数排序的时间复杂度为O(N+range),所以要求的范围越小这个排序效果越好

四.稳定性

定义:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的

注意:堆排序、快速排序、希尔排序、直接选择排序不是稳定的排序算法,而基数排序、冒泡排序、直接插入排序、折半插入排序、归并排序是稳定的排序算法。


总结

初级的排序算法就是这些了,还有一些不常用的和一些难的,等学了更多的知识我们再去了解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/563672.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【埋点探针】微信小程序SDK安装

一、下载微信小程序SDK埋点代码 选择Wechat&#xff0c;复制sdk代码 在项目根目录下&#xff0c;创建sdk文件&#xff0c;webfunny.event.js 二、在app.js文件中&#xff0c;引入埋点SDK代码 首先引入sdk代码 require("./webfunny.event.js")引入兼容代码&#x…

职业技能鉴定服务中心(新闻系统+证书查询系统)

后端采用ThinkPHP8&#xff0c;最新tp框架 前端采用divcss布局 数据库采用MySQL 采用三种技术实现新闻系统和证书查询系统 源码&#xff1a;git clone https://gitee.com/3539949703/certificate-website.git 效果图如下&#xff1a;

一套在线画图工具(突突图 Procviz)

突突图(Procviz)是一款面向跨平台作图平台。支持流程图、思维导图、框架图、组织架构图、ER图、网络拓扑图等。实现了多团体同时协作&#xff0c;实时同步&#xff0c;解决跨地域合作作图的问题。平台提供了丰富的模板和素材库&#xff0c;轻松完成作图&#xff0c;效率翻倍。 …

docker pull速度慢解决办法

在使用 Docker 时遇到拉取镜像速度慢的问题&#xff0c;可以使用国内的镜像源可以提高下载速度。 使用阿里镜像加速器 Docker 配置文件位于 /etc/docker/daemon.json。如果文件不存在&#xff0c;可以手动创建它。将以下内容添加到配置文件中&#xff1a; 整体复制执行命令&…

【设计模式】单例模式|最常用的设计模式

写在前面 单例模式是最常用的设计模式之一&#xff0c;虽然简单&#xff0c;但是还是有一些小坑点需要注意。本文介绍单例模式并使用go语言实现一遍单例模式。 单例模式介绍 简介 单例模式保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点。 使用场景&#…

web自动化系列-selenium的3种弹框操作(十二)

在进行功能测试时 &#xff0c;经常会遇到出现各种的弹出的提示 &#xff0c;比如删除数据给出提示 、做某个操作时也会弹框给出一些友好提示 &#xff0c;因为这些弹框都是做web操作时的一些常用组件 &#xff0c;所以&#xff0c;selenium就不得不支持这些组件 。 1.弹框介绍…

HarmonyOS开发环境搭建 移动开发 鸿蒙开发 ArkTS

&#x1f4dc;目录 &#x1f4a1; 环境搭建 &#x1f680;安装nodejs &#x1f935;安装ohpm &#x1f354;安装SDK &#x1f4a5;Emulator安装 &#x1f336;️新建ArkTs项目 &#x1f3c6;️ArkTS语言 ✨️基本语法 &#x1f388; 声明式UI描述 &#x1f371;组件 …

【C语言__函数栈帧的创建和销毁__复习篇9】

目录 前言 一、知识补充 二、分析创建和销毁的过程 三、前言问题回答 前言 本篇主要讨论以下问题&#xff1a; 1. 编译器什么时候为局部变量分配的空间 2. 为什么局部变量的值是随机的 3. 函数是怎么传参的&#xff0c;传参的顺序是怎样的 4. 形参和实参是什么关系 5. 函数…

【Linux 进程间通信】管道(三)

文章目录 1.管道的五种特征2.管道的四种情况 1.管道的五种特征 ①&#x1f34e;匿名管道只能用于有血缘关系的进程之间进行通信&#xff08;爷孙进程之间可以进行通信&#xff09;&#xff0c;常用于父子之间进行通信&#xff1b; ②&#x1f34e;管道内部&#xff0c;自带进…

若依后台管理系统(ruo-web)修改主题色,更改颜色值 (2024-04-22)

1、修改文件 setting.js 2、修改的文件路径 ruoyi-web/src/store/modules/setting.js 3、默认主题颜色 #409EFF&#xff0c;改新的颜色值&#xff0c;刷新就好了 4、修改主题颜色 还可以用户自己更换&#xff0c;但这个更换只是存储在浏览器中&#xff0c;清除缓存之后还是…

【ARM 裸机】C 语言 led 驱动

前面刚学习了汇编 led 驱动的编写和验证&#xff0c;现在开始就要进入 C 语言 led 驱动编写与验证了 ! 1、C 语言运行环境构建 1.1、设置处理器模式 使 6ULL 处于 SVC 模式下&#xff0c;之前已经提到了处理器的九种模式&#xff0c;参考&#xff1a;【ARM 裸机】汇编 led 驱…

【Linux系统编程】第六弹---权限的概念

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、什么是权限 2、权限的本质 3、Linux中的用户 4、Linux中文件的权限 4.1、文件访问者的分类(角色) 4.2、文件类型和访问权…

计算机经典黑皮书分享

计算机经典黑皮书是一套计算机科学丛书&#xff0c;其中包含了多本计算机科学领域的经典教材 提供了全面的知识体系&#xff1a;黑皮书涵盖了计算机科学的多个领域&#xff0c;如计算机组成与设计、操作系统、数据库、人工智能等。它们深入浅出地介绍了相关领域的基本概念、原…

WAF攻防-漏洞发现协议代理池GobyAwvsXray

知识点 1、Http/s&Sock5协议 2、Awvs&Xray&Goby代理 3、Proxifier进程代理使用 4、Safedog&BT&Aliyun防护在漏洞发现中&#xff0c;WAF会对三个方向进行过滤拦截&#xff1a; 1、速度频率问题&#xff08;代理池解决&#xff09; 2、工具的指纹被识别&am…

从零开始学 langchain 之搭建最小的 RAG 系统

RAG 可以说是 23 年以来到现在&#xff0c;最为火热的大模型应用技术了&#xff0c;很多人都有了很多经典的研究。而对于新人来说&#xff0c;有些代码十分复杂&#xff0c;导致只看表象并不理解其原理。今天&#xff0c;就利用 langchain 和大家一起搭建一个最简单的 RAG 系统…

JAVA学习笔记27(异常)

1.异常 ​ *异常(Exception) ​ *快捷键 ctrl alt t 选中try - catch ​ *如果进行了异常处理&#xff0c;那么即使出现了异常&#xff0c;程序可以继续执行 1.1 基本概念 ​ *在Java语言中&#xff0c;将程序执行中发生的不正常情况称为"异常"(开发过程中的语…

Xinlinx原语在哪查看如何使用/原语示例

1.打开Vivado 2.点击Tools&#xff0c;选择Language Templates 3.选择Language类型、Device Primitive Instantiation&#xff08;原语&#xff09;、Kintex-7&#xff08;芯片系列&#xff09;&#xff0c;之后可以选择自己需要使用的类型&#xff0c;这里以分布式RAM为例&am…

大一考核题解

在本篇中&#xff0c;将尽力使用多种解法&#xff0c;来达到一题多练的效果。 1&#xff1a; 1.原题链接&#xff1a; 238. 除自身以外数组的乘积 - 力扣&#xff08;LeetCode&#xff09; 这道题首先一眼肯定想到拿整体的积除以当前元素&#xff0c;将结果作为ans&#xff0c;…

Mysql的【存储引擎】之【InnoDB】与【MyISAM】的区别

目录 1.存储引擎在 MyISAM 和 InnoDB 有什么区别 2.Mysql 5.7 默认的存储引擎是什么 3.一个简单例子&#xff08;如果非要使用【MyISAM】存储引擎 &#xff09; 4.2009年写的留言板程序的数据&#xff08;存储引擎是&#xff1a;【MyISAM】&#xff09; 5.mysql 8.0 可以使…

Java学习笔记26(枚举和注解)

1.枚举和注解 1.1 枚举 ​ 1.枚举(enumeration) ​ 2.枚举是一组常量的集合 ​ 3.枚举属于一种特殊的类&#xff0c;里面只包含一组有限的特定的对象 1.枚举应用案例 ​ 1.不需要提供setXxx方法&#xff0c;因为枚举对象值通常为只读 ​ 2.对枚举对象/属性使用final st…