数据结构 - 栈和队列

本篇博客将介绍栈和队列的定义以及实现。

1.栈的定义
        栈是一种特殊的线性表,只允许在固定的一端进行插入和删除数据,插入数据的一端叫做栈顶,另一端叫做栈底。栈中的数据遵守后进先出的原则 LIFO (Last In First Out)
        插入数据的操作称为压栈/进栈/入栈。
        删除数据的操作称为出栈。
        压栈和出栈的操作都在栈顶。

2.  栈的实现
栈的实现可以利用数组或者链表,在此处由于数组在尾部插入和删除数据较为简单,因此我们利用数组实现栈的相关操作。数组的结构如下:

因此我们需要实现以下功能
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;    //栈顶
	int capaicty;
}ST;

void STInit(ST* pst); //初始化
void STDestroy(ST* pst);//内存释放
void STPush(ST* pst, STDataType x);//压栈
void STPop(ST* pst);//出栈
STDataType STTop(ST* pst);//返回栈顶数据
bool STEmpty(ST* pst);//判断栈是否为空
int STSize(ST* pst);//返回栈中数据个数
 接下来,我们可以初始定义一个结构体:
	ST st;
 具体函数代码如下:
void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	//pst->top = -1; //top指向栈顶数据
	pst->top = 0;  //top指向栈顶数据的下一个
	pst->capaicty = 0;
}

void STDestroy(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->top = 0;
	pst->capaicty = 0;
}

void STPush(ST* pst, STDataType x)
{
	if (pst->top == pst->capaicty)
	{	
		int newCapacity = pst->capaicty == 0 ? 4 : pst->capaicty * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		pst->a = tmp;
		pst->capaicty = newCapacity;
	}
	pst->a[pst->top] = x;
	pst->top++;
}

void STPop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	pst->top--;
}

STDataType STTop(ST* pst)
{	
	assert(pst);
	assert(!STEmpty(pst));
	return pst->a[pst->top - 1];
}


bool STEmpty(ST* pst)
{
	assert(pst);
	return pst->top == 0;//等于0为真
}

int STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}
需要注意的是,当打印栈时,则是通过 STDataType STTop(ST* pst); 返回栈顶数据打印,然后栈顶数据出栈,再打印新的栈顶。直到栈为空,代码如下:
while (!STEmpty(&st))
{
	printf("%d ", STTop(&st));
	STPop(&st);
}
3. 队列的定义 
        队列只允许一端进行插入数据的操作,二在另一端删除数据的一种特殊线性表,队列数据按照先进先出入队列 FIFO (First in FIrst Out)
        队尾插入数据,对头删除数据。

4. 队列的实现 
同样的,队列的实现也可以利用数组和链表实现,在此处使用单链表较为简单,因为入队相当于单链表的尾插,出队相当于单链表的头删。

因此我们需要实现以下功能 :
typedef int  QueueDataType;

typedef struct QueueNode //定义每个结点的结构
{
	struct QueueNode* next;
	QueueDataType data;
}QNode;

typedef struct Queue //标识整个队列
{
	QNode* phead;
	QNode* ptail;
	int size;
}Queue;

void  QueueInit(Queue* pq);//队列初始化
void  QueueDestory(Queue* pq);//内存释放
void  QueuePush(Queue* pq, QueueDataType x);//入队
void  QueuePop(Queue* pq);//出队
QueueDataType QueueFront(Queue* pq);//队头数据
QueueDataType QueueBack(Queue* pq);//队尾数据
int QueueSize(Queue* pq);//队列节点个数
bool QueueEmpty(Queue* pq);//判断空队列
接下来,我们定义初始结构体:
Queue q;
 具体实现代码如下:
void  QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}
void  QueueDestory(Queue* pq) 
{
	assert(pq);
	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}
void  QueuePush(Queue* pq, QueueDataType x) 
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail\n");
		return;
	}
	newnode->data = x;
	newnode->next = NULL;
	if (pq->ptail == NULL)
	{
		assert(pq->phead == NULL);
		pq->phead = pq->ptail = newnode;
	}
	else 
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;

	}
	pq->size++;
}

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	//1. 一个节点
	//2. 多个节点
	if (pq->phead->next == NULL)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	pq->size--;
}
QueueDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->phead->data;
}
QueueDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->ptail->data;
}
int QueueSize(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->size;
}
bool QueueEmpty(Queue* pq) 
{
	assert(pq);
	return pq->phead == NULL && pq->ptail == NULL;//空 turn
	//return pq->size;
}

同样的,返回对头数据打印,然后对头数据出队,再打印新的对头。直到队列为空,代码如下: 

while (!QueueEmpty(&q))
{
	printf("%d ", QueueFront(&q));
	QueuePop(&q);
}

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

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

相关文章

设计模式-行为型模式-迭代器模式

迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。[DP] 首先,定义一个接口Iterator,它包含了遍历聚合对象所需的方法: public interface Iterato…

spring boot 集成 mysql ,mybatisplus多数据源

1、需要的依赖&#xff0c;版本自行控制 <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId> </dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java<…

python基础——输入与输出【input 和 print】

&#x1f4dd;前言&#xff1a; 上一篇文章python基础——入门必备知识中讲解了一些关于python的基础知识&#xff0c;可以让我们更好的理解程序代码中内容的含义&#xff0c;不至于一头雾水。今天我就来介绍一下&#xff0c;python中两个常见的输入和输出语句 input 和 print …

论文阅读之Multimodal Chain-of-Thought Reasoning in Language Models

文章目录 简介摘要引言多模态思维链推理的挑战多模态CoT框架多模态CoT模型架构细节编码模块融合模块解码模块 实验结果总结 简介 本文主要对2023一篇论文《Multimodal Chain-of-Thought Reasoning in Language Models》主要内容进行介绍。 摘要 大型语言模型&#xff08;LLM…

Dockerfile的使用,怎样制作镜像

Docker 提供了一种更便捷的方式&#xff0c;叫作 Dockerfile docker build命令用于根据给定的Dockerfile构建Docker镜像。 docker build命令参数&#xff1a; --build-arg&#xff0c;设置构建时的变量 --no-cache&#xff0c;默认false。设置该选项&#xff0c;将不使用Build …

Ubuntu18/20运行ORB-SLAM3

ORB-SLAM3复现(ubuntu18/20) 文章目录 ORB-SLAM3复现(ubuntu18/20)1 坐标系与外参Intrinsic parameters2 内参Intrinsic parameters2.1 相机内参① 针孔模型Pinhole② KannalaBrandt8模型③ Rectified相机 2.2 IMU内参 3 VI标定—外参3.1 Visual calibration3.2 Inertial calib…

继承中 隐藏和重写的区别

隐藏&#xff08;重定义&#xff09;&#xff1a;在不同作用域中&#xff08;不同类&#xff09;&#xff0c;函数名相同&#xff0c;当子类对象想要调用这个函数的时候&#xff0c;只能调用到子类中的这个同名函数&#xff0c;父类中的那个被隐藏。子类对象想要调用父类中的那…

S32 Design Studio PE工具配置ADC

工具配置 我这个K1芯片有两个ADC驱动&#xff0c;也就有两个components&#xff0c;点开之后每个components都有四个选项卡converter转换器、channel通道、compare比较器、average求平均。 配置引脚 配置之前&#xff0c;得先配置好引脚&#xff0c;哪个引脚用来采集ADC。 每…

LangChain Experssion Language之CookBook(一)

目录 LangChain Experssion Language简介 CookBook示例大赏 Prompt LLM&#xff1a;正经本分事儿 RAG&#xff1a;检索的时候用上用户自己的数据吧 Multiple chains&#xff1a;玩转chain的叠加合并 Querying a SQL DB&#xff1a;根据用户的问题写SQL检索数据库 Agent…

uniapp使用华为云OBS进行上传

前言&#xff1a;无论是使用华为云还是阿里云&#xff0c;使用其产品的时候必须阅读文档 1、以华为云为例&#xff0c;刚接触此功能肯定是无从下手的情况&#xff0c;那么我们需要思考&#xff0c;我们使用该产品所用到的文档是什么 2、我们要使用obs 文件上传&#xff0c;肯…

iOS-系统弹窗调用

代码&#xff1a; UIAlertController *alertViewController [UIAlertController alertControllerWithTitle:"请选择方式" message:nil preferredStyle:UIAlertControllerStyleActionSheet];// style 为 sheet UIAlertAction *cancle [UIAlertAction actionWithTit…

Docker基础教程 - 9 常用容器部署-Tomcat

更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 9 常用容器部署-Tomcat 下面介绍一下常用容器的部署。可以先简单了解下&#xff0c;用到再来详细查看。 在 Docker 中部署 Tomcat 容器。 9.1 搜索镜像 首先搜索镜像&#xff0c;命令&…

来说说看到的求职路上可以提高的地方——简历

要进行求职的时候应该遇到的第一件事情就是简历。 随着看到的简历越来越多&#xff0c;也发现了一些问题&#xff0c;来开个帖子来说说这些问题。 格式 让参加面试的人最头疼的地方就是简历格式没有空格。 最近发现好多人的简历格式上都不空格&#xff0c;很多内容完全都在…

植物病虫害:YOLO玉米病虫害识别数据集

玉米病虫害识别数据集&#xff1a;玉米枯萎病&#xff0c;玉米灰斑病&#xff0c;玉米锈病叶&#xff0c;粘虫幼虫&#xff0c;玉米条斑病&#xff0c;黄二化螟&#xff0c;黄二化螟幼虫7类&#xff0c;yolo标注完整&#xff0c;3900多张图像&#xff0c;全部原始数据&#xff…

el-table-column嵌套el-form-item不能进行校验问题解决

项目为vue3elementPlus开发的项目 业务要求&#xff1a;table表格展示数据&#xff0c;其中有一行是ip地址可展示可修改&#xff0c;此处要求增加自定义校验规则 先看一下效果&#xff1a; 此处先描述一下&#xff0c;问题出在了哪里&#xff0c;我将el-table的data,使用一个…

LabVIEW质谱仪开发与升级

LabVIEW质谱仪开发与升级 随着科技的发展和实验要求的提高&#xff0c;传统基于VB的质谱仪系统已经无法满足当前的高精度和高效率需求。这些系统通常存在着功能不全和操作复杂的问题&#xff0c;影响了科研和生产的进度。为了解决这些问题&#xff0c;开发了一套基于LabVIEW开…

考研复习C语言初阶(3)

目录 一.函数是什么? 二.C语言中函数的分类 2.1库函数 2.2自定义函数 三.函数的参数 3.1实际参数&#xff08;实参&#xff09; 3.2 形式参数&#xff08;形参&#xff09; 四.函数的调用 4.1 传值调用 4.2 传址调用 五. 函数的嵌套调用和链式访问 5.1 嵌套调用 5…

Nginx 基础知识及实例解析

一、简介 Nginx (“engine x”) 是一个高性能的 HTTP 和反向代理服务器&#xff0c;特点是占有内存少&#xff0c;并发能力强&#xff0c;目前使用最多的就是负载均衡。Nginx 可以作为静态页面的 web 服务器&#xff0c;同时还支持 CGI 协议的动态语言&#xff0c;比如 perl、…

探索考古文字场景,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建文本考古场景下的甲骨文字符图像检测识别系统

甲骨文是一种非常历史悠久的古老文字&#xff0c;在前面我们基本上很少有涉及这块的内容&#xff0c;最近正好在做文字相关的项目开发研究&#xff0c;就想着基于甲骨文的场景来开发对应的检测识别系统&#xff0c;在前文中我们基于YOLOv7开发构建了在仿真数据实验场景下的目标…

Mamba-minimal Mamba的最小限度实现 (一)

文章目录 参数和数据尺寸约定class MambaBlockdef forwarddef __ int__def ssmdef selective_scan johnma2006/mamba-minimal: Simple, minimal implementation of the Mamba SSM in one file of PyTorch. (github.com) manba的简单最小限度实现&#xff0c;和原始论文实现stat…