【数据结构】--- 栈和队列

news2024/11/13 15:52:35

前言

        前面学习了数据结构的顺序表、单链表、双向循环链表这些结构;现在就来学习栈和队列,这里可以简单的说栈和队列是具有特殊化的线性表

一、栈

        1.1、栈的概念和结构

        栈是一种遵循先入后出逻辑的线性数据结构。

        栈是一种特殊的线性表,它只允许在固定的一端进行插入和删除元素操作;进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。

        栈中的数据元素遵循先进后出(LIFO)的原则;也就是所谓的后来者居上

        如图所示,我们把堆叠元素的顶部称为“栈顶”,底部称为“栈底”。将元素添加到栈顶的操作叫做“入栈”,删除栈顶的元素叫做“出栈”。

从图中我们可以看出,栈数据的出栈和入栈都在栈顶;这就是栈数据先进后出的原则。

        1.2、栈的实现

        栈的实现可以使用数组来实现,当然也可以使用链表来实现,这里就用数组来实现栈。

用数组来实现栈就和之前顺序表的实现有些相似,对顺序表不了解的话可以看一下前面的

【数据结构】--- 顺序表

首先先来看一下,栈这个数据结构都要实现哪些功能:

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

typedef int SType;
typedef struct Stack
{
	SType* arr;
	int size;  //栈顶
	int num;   //空间大小
}Stack;

//初始化
void STInit(Stack* ps);
//判断栈是否为空
bool STEmpty(Stack* ps);
//入栈
void STPush(Stack* ps, SType x);
//出栈
void STPop(Stack* ps);
//取栈顶数据
SType STtop(Stack* ps);
//获取栈中数据个数
int STSize(Stack* ps);
//栈的销毁
void STDesTroy(Stack* ps);

1.2.1、初始化

//初始化
void STInit(Stack* ps)
{
	assert(ps);
	ps->arr = NULL;
	ps->size = ps->num = 0;
}

1.2.2、判断栈是否为空

        判断栈是否为空?如果为空,就返回true;如果不为空,就返回false。

//判断栈是否为空
bool STEmpty(Stack* ps)
{
	assert(ps);
	return ps->size == 0;
}

1.2.3、入栈

        入栈,在栈顶插入数据(和顺序表尾插相似)

//入栈
void STPush(Stack* ps, SType x)
{
	assert(ps);
	//判断空间大小是否足够
	if (ps->num <= ps->size)
	{
		int newnum = (ps->num == 0) ? 4 : 2 * ps->num;
		SType* tmp = (SType*)realloc(ps->arr, newnum * sizeof(Stack));
		if (tmp == NULL)
		{
			perror("realloc filed");
			exit(1);
		}
		ps->arr = tmp;
		ps->num = newnum;
	}
	ps->arr[ps->size++] = x;
}

1.2.4、出栈        

        出栈,删除栈顶的数据(和顺序表尾删相似)

//出栈
void STPop(Stack* ps)
{
	assert(ps); //不能传NULL
	assert(!STEmpty(ps));  //栈不能为空
	ps->size--;
}

1.2.5、取栈顶数据

        取栈顶数据,将栈顶的数据返回即可

//取栈顶数据
SType STtop(Stack* ps)
{
	assert(ps); //不能传NULL
	assert(!STEmpty(ps));  //栈不能为空
	return ps->arr[ps->size - 1];
}

1.2.6、获取栈中数据个数

        获取栈中数据个数,这里size就是栈的数据个数

//获取栈中数据个数
int STSize(Stack* ps)
{
	assert(ps);
	return ps->size;
}

1.2.7、销毁栈

        这里,动态开辟的空间要进行释放,养成好习惯

//栈的销毁
void STDesTroy(Stack* ps)
{
	assert(ps);
	if (ps->arr)
		free(ps->arr);
	ps->arr = NULL;
	ps->size = ps->num = 0;
}

二、队列

        2.1、队列的概念和结构

        队列,是一种遵循先入先出规则的线性数据结构。

        顾名思义,队列模拟了现实生活中排队现象,即新来的人不断加入队列队尾,而位于对头的人逐个离开

        队列只允许在一端进行插入数据操作,在另一端进行删除数据操作

如图,我们将队列头部称为“对头(队首)”,尾部称为“队尾”;

将把元素插入到队尾操作称为“入队”,删除队首的数据的操作称为“出队”

        2.2、队列的实现

队列的实现,这里也是即可以使用数组来实现,也可以使用链表来实现;这里使用链表来实现队列

 用链表来实现队列就和之前链表的实现有些相似,对单链表不了解的话可以看一下前面的

【数据结构】--- 单链表的实现

        先来卡看队列的基本功能

typedef int QType;
typedef struct QueueNode //队列节结构
{
	QType data;
	struct QueueNode* next;
}QueueNode;
typedef struct Queue //队列结构
{
	int size;   //队列中的数据个数
	QueueNode* phead; //队头
	QueueNode* ptial; //队尾
}Queue;

//初始化
void QueueInit(Queue* pq);
//判断队列是否为空
bool QueueEmpty(Queue* pq);
//入队列--从队尾删除数据
void QueuePush(Queue* pq);
//出队列--从对头删除数据
void QueuePop(Queue* pq);
//取队头数据
QType QueueFront(Queue* pq);
//取队尾数据
QType QueueBack(Queue* pq);
//获取队列数据个数
int QueueSize(Queue* pq);
//销毁队列
void QueueDesTroy(Queue* pq);

2.2.1、初始化

//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = pq->ptial = NULL;
	pq->size = 0;
}

2.2.2、判断队列是否为空

        如果队列为空,返回true;如果不为空,返回false

//判断队列是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->size == 0;
}

2.2.3、入队列

        从队列尾部插入数据,与单链表尾插类似

//入队列--从队尾插入数据
void QueuePush(Queue* pq, QType x)
{
	assert(pq);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	newnode->data = x;
	newnode->next = NULL;
	if (QueueEmpty(pq)) // 队列为空
	{
		pq->phead = pq->ptial = newnode;
	}
	else {  //队列不为空
		pq->ptial->next = newnode;
		pq->ptial = newnode;
	}
	pq->size++;
}

2.2.4、出队列

        从队头删除数据,与链表头删类似

//出队列--从对头删除数据
void QueuePop(Queue* pq)
{
	assert(pq);  //不能传NULL
	assert(!QueueEmpty(pq));  //队列不能为空
	QueueNode* del = pq->phead;
	pq->phead = pq->phead->next;
	if (pq->size == 1)  //队列只有一个节点
	{
		pq->ptial = NULL;
	}
	pq->size--;
	free(del);
	del = NULL;
}

2.2.5、取队头数据

        取队头的数据返回

//取队头数据
QType QueueFront(Queue* pq)
{
	assert(pq);  //不能传NULL
	assert(!QueueEmpty(pq));  //队列不能为空
	return pq->phead->data;
}

2.2.6、取队尾数据

        取队尾数据返回

//取队尾数据
QType QueueBack(Queue* pq)
{
	assert(pq);  //不能传NULL
	assert(!QueueEmpty(pq));  //队列不能为空
	return pq->ptial->data;
}

2.2.7、获取队列数据个数

        获取队列数据个数,这里实现队列时,定义了一个结构体成员size记录队列数据个数。

//获取队列数据个数
int QueueSize(Queue* pq)
{
	assert(pq);  //不能传NULL
	return pq->size;
}

2.2.8、销毁队列

        队列是由链表实现的,而链表是动态开辟的内存,记得释放。

//销毁队列
void QueueDesTroy(Queue* pq)
{
	assert(pq);  //不能传NULL
	assert(!QueueEmpty(pq));  //队列不能为空
	QueueNode* pcur = pq->phead;
	while (pcur)
	{
		QueueNode* del = pcur;
		pcur = pcur->next;
		free(del);
		del = NULL;
	}
	pq->phead = pq->ptial = NULL;
	pq->size = 0;
}

感谢各位大佬支持并指出问题,

                        如果本篇内容对你有帮助,可以一键三连支持以下,感谢支持!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

矿场运输车4G视频监控管理解决方案

一、背景介绍 随着科技的不断进步和智能化时代的来临&#xff0c;矿业运输行业也在寻求更高效率与安全的管理手段。矿场运输车4G视频监控管理解决方案是一种基于4G网络技术的视频监控系统&#xff0c;专门用于监测和管理矿场内运输车辆的工作状态和安全情况。该方案为矿场运输…

【linux】在多核CPU下,好像看到不同进程在不同CPU调度

在2353这行打印的情况来看&#xff0c;操作系统好像给不同的进程分配不同的CPU&#xff0c;从上图来看&#xff0c;同一个进程好像基本使用的相同的CPU&#xff1a; 其实摸索syscall文件系统操作&#xff0c;本意是想找到内核文件系统中文件的创建&#xff0c;写入&#xff0c;…

C 观察者模式 Demo

目录 一、基础描述 二、Demo 最近需要接触到 MySQL 半同步插件&#xff0c;发现其中用到了观察者模式&#xff0c;之前没在 C 中用过&#xff0c;遂好奇心驱使下找了找资料&#xff0c;并写了个 Demo。 一、基础描述 观察者设计模式&#xff08;Observer Pattern&#xff0…

ts踩坑!使用可选链 ?.处理可能遇到的 undefined 或 null 值的情况,但是仍然收到一个关于可能为 undefined 的警告!

在 TypeScript 中&#xff0c;当你使用可选链&#xff08;Optional Chaining&#xff09;?. 时&#xff0c;你其实已经处理了可能遇到的 undefined 或 null 值的情况。但是&#xff0c;如果你仍然收到一个关于可能为 undefined 的警告&#xff0c;这可能是因为 TypeScript 的类…

Mybatis——快速入门

介绍 MyBatis是一款优秀的持久层&#xff08;Dao层&#xff09;框架&#xff0c;用于简化JDBC的开发。MyBatis 底层是基于 JDBC 实现的&#xff0c;它封装了 JDBC 的大部分功能&#xff0c;使得数据库操作更加便捷和高效。同时&#xff0c;MyBatis 也保留了 JDBC 的灵活性&…

unity2D游戏开发03状态控制

多态和动画 建立player-idle动画&#xff0c;取玩家最后两个图片 选中playcontroller控制器 将玩家动画拖进去 右键player-idle,选择set as layer Default state 右键点击Any State ,点击Make Transition 结果 动画参数 动画参数是动画控制器定义的变量&#xff0c;点击Param…

Matlab arrayfun 与 bsxfun——提高编程效率的利器!

许多人知道 MATLAB 向量化编程&#xff0c;少用 for 循环 可以提高代码运行效率&#xff0c;但关于代码紧凑化编程&#xff0c; arrayfun 与 bsxfun 两个重要函数却鲜有人能够用好&#xff0c;今天针对这两个函数举例说明其威力。 Matlab arrayfun 概述 arrayfun 是 Matlab …

one-api 源码调试配置

本文主要介绍通过 VSCode 调试 one-api 源码。 一、环境配置 1.1 VSCode 和 one-api 安装 首先,确保已经安装了 VSCode(下载链接)和 one-api 源码(下载链接)已下载并安装了依赖 1.2 安装 Go 插件 在 VSCode 中,安装 Go 插件。 1.3 安装 dlv 调试包 可以通过下载源码…

EEtrade:现货黄金盈利计算方法

现货黄金交易作为一种极具吸引力的投资方式&#xff0c;其盈利计算涉及多个关键因素&#xff0c;投资者需深入理解这些因素&#xff0c;才能准确评估交易结果&#xff0c;并制定科学的投资策略。 一、现货黄金基本盈利计算&#xff1a; 利润公式&#xff1a; 利润 (收盘价 -…

docker部署mysql8.x版本,编写shell脚本自动部署安装mysql

docker部署mysql8.x版本&#xff0c;编写shell脚本自动部署安装mysql **1.**先自行安装好docker环境&#xff0c;docker的镜像注册中心最好是国内的&#xff0c;例如执行一下命令直接修改docker配置&#xff0c; cat <<EOF > /etc/docker/daemon.json {"regist…

LabVIEW学习-LabVIEW处理带分隔符的字符串从而获取数据

带分隔符的字符串很好处理&#xff0c;只需要使用"分隔符字符串至一维字符串数组"函数或者"一维字符串数组至分隔符字符串"函数就可以很轻松地处理带分隔符地字符串。 这两个函数所在的位置为&#xff1a; 函数选板->字符串->附加字符串函数->分…

在STM32嵌入式中C/C++语言对栈空间的使用

像STM32这样的微控制器在进入main函数之前需要对栈进行初始化。可以说栈是C语言运行时的必要条件。我们知道栈实际上是一块内存空间&#xff0c;那么这块空间都用来存储什么呢&#xff1f;有什么办法能够优化栈空间的使用&#xff1f; 栈空间保存的内容 栈是一个先入后出的数据…

学术研讨 | 区块链网络体系结构研讨会顺利召开

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 近日&#xff0c;国家区块链技术创新中心组织了“区块链网络体系结构研讨会”&#xff0c;会议面向跨域交互多、计算规模大、数据管理复杂、性能与扩展性要求高等特征的区块链网络的体系结构展开交流研讨&…

ShareDB:构建实时应用从未如此简单

项目介绍 ShareDB 是一个支持多用户实时协作的全栈库&#xff0c;适用于构建各种需要同步数据更新的在线应用&#xff0c;如在线文档编辑器、实时仪表板和多玩家游戏等。 它提供了一套全面的实时同步和多用户协作解决方案&#xff0c;具备异步最终一致性、实时查询订阅、数据库…

Win11 操作(四)g502鼠标连接电脑不亮灯无反应

罗技鼠标连接电脑不亮灯无反应 前言 罗技技术&#x1f4a9;中&#x1f4a9;&#xff0c;贴吧技术神中神&#xff01; 最近买了一个g502&#xff0c;结果买回来直接插上电脑连灯都不亮&#xff0c;问了一下客服。客服简单的让我换接口&#xff0c;又是下载ghub之类的&#xf…

ESP8266用AT指令实现连接MQTT

1准备工作 硬件&#xff08;ESP8266&#xff09;连接电脑 硬件已经烧入了MQTT透传固件 2实现连接 2-1&#xff08;进入AT模式&#xff09; 打开串口助手发送如下指令 AT 2-2&#xff08;复位&#xff09; ATRST 2-3&#xff08;开启DHCP&#xff0c;自动获取IP&#x…

SpringBoot+Vue(3)Excel的在线预览

一、思路 在Spring Boot和Vue.js的组合中实现Excel文件的在线预览功能&#xff0c;通常涉及到几个关键步骤&#xff1a;文件上传、文件存储、文件读取、以及通过前端展示Excel内容。由于Excel文件本身不是直接可以在网页上渲染的格式&#xff0c;我们通常需要将Excel文件转换为…

vue3创建vite项目

一、创建vue3 vite项目&#xff1a; 命令行创建&#xff1a;npm create vitelatest vue3-tdly-demo -- --template vue (1)先进入项目文件夹&#xff0c;cd vue3-tdly-demo (2)之后执行&#xff0c; npm install (3)最后运行&#xff0c;npm run dev 将main.js文件内容改成…

ML.NET:一个.NET开源、免费、跨平台的机器学习框架

前言 今天大姚给大家分享一个.NET开源、免费、跨平台&#xff08;支持Windows、Linux、macOS多个操作系统&#xff09;的机器学习框架&#xff1a;ML.NET。并且本文将会带你快速使用ML.NET训练一个属于自己的图像分类模型&#xff0c;对图像进行分类。 ML.NET框架介绍 ML.NET…

计算机网络之网络基础(含图解和知识点思维导图通俗易懂)

绪论​ “一个人在科学探索的道路上&#xff0c;走过弯路&#xff0c;犯过错误&#xff0c;并不是坏事&#xff0c;更不是什么耻辱&#xff0c;要在实践中勇于承认和改正错误。——爱因斯坦”。本章将是网络的第一章&#xff0c;计算机网络是我们计算机行业必须了解并掌握的知识…