数据结构---栈队列

栈和队列是我们数据结构中经常使用的数据结构,所以现在来了解一下栈和队列。


特点:

栈是一种特殊的线性表,其中进行数据插入和弹出的部分叫做栈顶,另一端叫做栈底。

只允许数据从栈顶压入,从栈顶弹出即先进后出的特点,也称LIFO  (Last In First Out)。

压栈:将数据从栈顶压入栈中。

弹栈:将栈顶的数据从栈中弹出。

实现:

接下来基于C语言来实现一个栈,及其增删查改功能:

栈的初始化:

对于栈,肯定要和链表一样进行数据结构定义,但是对于链表我们只需要开一个大小的空间即可,但是栈可能会压入多个数据,我们无法得知具体数目,所以我们一开始选择将栈的大小设置成为4,后续对栈容量进行动态扩容即可。

typedef struct stack {int* data;int size, top;
}stack;stack* Stack_Init() {stack* p = (stack*)malloc(sizeof(stack));p->data = (int*)malloc(sizeof(int) * 4);p->size = 4;p->top = -1;return p;
}

栈的销毁:

既然我们使用malloc函数来分配了栈的内存,那么我们就需要设置一个函数来释放栈的内存空间:


void Stack_Free(stack* p) {if (p == NULL) {return;}free(p->data);free(p);return;
}

栈的压入操作:

在上文,我们考虑到了由于栈要压入未知数据量,所以我们不能固定栈的大小,则需要动态内存开辟,实现栈的容量的增加。

但是又考虑到另外一个问题,我们要增加多少容量呢?当数据量很大时,只增加个位数或十位数级别的容量对栈的帮助不大,任然需要频繁增加栈的容量,那么我们每次改变栈的容量时,将栈的容量翻一倍即可,以达到减少扩容次数的需要。

在思考完栈的容量管理后,栈的压入就变得简单了,只需要将栈的size位置放入数据并且让size+1即可。

int Stack_Push(int val, stack* p) {if ( (p->top) + 1 == p->size || p == NULL) {p->data=(int*)realloc(p,p==NULL?sizeof(int)*4:2*p->size*sizeof(int));}p->data[p->top + 1] = val;p->top += 1;return 1;
}

查询栈顶元素:

由于栈后进先出的特性,我们只能查找到栈顶元素

int top(stack* p) {if (p->top == -1) {return NULL;}return p->data[p->top];
}

栈的判空:

当栈中不含有元素时,我们则不能继续弹出栈顶的元素,所以我们需要判断栈内此时是否存有元素。

int Empty(stack* p) {if (p == NULL) {return NULL;}return (p->top == -1);
}

栈的弹出操作:

栈的弹出存在一种特殊情况即栈为空时弹出元素,此时弹出操作则为违法操作。

所以在弹出操作前,我们需要调用判空函数来判断弹出操作是否合法。

若栈内不为空,则弹出栈顶元素;若栈内为空,则返回NULL即可。

int Stack_Pop(stack* p) {if (Empty(p) ==0) {return 0;}p->top -= 1;return p->data[(p->top) + 1];
}

此外栈还可以由链表实现,由链表实现的栈则省去了栈的扩容操作,节约了时间。


队列:

特点:

队列也是一种特殊的线性表,其中进行数据插入的部分叫做队尾,弹出数据的部分叫做队首。

队列只允许数据从队尾压入,从队首弹出。

具有先进先出的特点,也称FIFO  (First In First Out)。

实现:

接下来是基于C语言实现队列及其增删查改的操作:

队列的初始化:

队列与栈相似,我们都需要对其进行数据结构的定义。

在定义完数据结构后,我们任然需要与栈一样考虑队列的大小管理,所以我们将队列的大小初始化为4。

typedef struct queue {int* data;int size, count, head, tail;
}queue;//初始化队列
queue* Init_Queue(int n) {queue* p = (queue*)malloc(sizeof(queue));p->data = (int*)malloc(sizeof(int)*4);//让count,head,size,tail为0p->count = p->head = p->size = p->tail = 0;//返回该队列的首地址return p;
}

队列的销毁:

由于队列使用了malloc函数分配了内存,所以我们需要手动销毁queue的内存。

//定义一个函数用于释放队列的空间
void Queue_Free(queue* head) {if (head == NULL) {return;}free(head->data);free(head);return;
}

队列的插入操作:

队列与栈一样,当队列容量即将满时,我们将队列的大小翻一倍。

然后将数据插入到队列中即可:

void Queue_Insert(queue* p,int val){if(p->data==NULL || (p->count+1==p->size)){p->data=(int*)realloc(p->data,p->data==NULL?4:2*sizeof(int)*p->size);p->size*=2;}p->data[p->count++]=val;p->tail++;return;
}

队列的判空:

队列与栈一致,当队列为空时,弹出队首元素为违法操作,所以我们需要对队列进行判空


int Empty(queue* p) {return (p->count == 0);
}

队列的弹出操作:

与栈操作一致,当队列为空时,弹出元素为违法操作;队列不为空时,则弹出队首元素。

int Delete(queue* p) {//判断队列中是否为空if (Empty(p)) {return 0;}//让队首向后一个,含有的数据-1p->head += 1;p->count -= 1;return  p->data[p->head-1];
}

查询队首元素:

对于队列,我们只能查询队首的元素。

//输出队首的数据
int Queue_Front(queue* p) {return p->data[p->head];
}

队列也可以由链表实现,你能构思并且设计一个由链表构成的队列吗?


至此,队列和栈的讲解到此结束。

如果我的文章对你有所帮助,不妨给我个关注何点赞吧。

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

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

相关文章

最佳实践:REST API 的 HTTP 请求参数

HTTP 请求中的请求参数解释 当客户端发起 HTTP 请求 时,它们可以在 URL 末尾添加请求参数(也叫查询参数或 URL 参数)来传递数据。这些参数以键值对的形式出现在 URL 中,方便浏览和操作。 请求参数示例 以下是一些带有请求参数的…

JS-Lodash工具库

文档:Lodash Documentation orderBy函数:根据条件进行排序 注:第一个是要排序的数组,第二个是根据什么字段进行排序,第三个是排序的方式(desc倒序) 安装方式:Lodash npm i lodash…

小型企业网络组网与配置仿真实验

实验要求如下: 我这里以学号46为例 一、IP 地址规划表 (一)主类网络 (二)子网划分 需要自己计算有效ip范围 在C类主网络192.168.46.0/24中,我们需要先了解这个网络的子网掩码为255.255.255.0,其二进制…

『ZJUBCA MeetUP』 5月25日线下活动——Aptos 链的动态与应用

2024 求是创新 ZJUBCA Sponsored by the ALCOVE Community TIME:2024/05/25 ADD:浙江大学紫金港校区 --- Alcove 是 Aptos 公链与 Alibaba Cloud 共同打造的亚洲首个 Move 开发者社区,致力于支持开发者使用 Move 语言构建下一代 Web3 应用&am…

TPM之VMK密封

本篇文章主要介绍基于TPM的Bitlocker全盘加密时,VMK密钥的密封(Seal)流程,至于TPM、Bitlocker、密钥保护器、VMK密钥等这些东西是什么,这里不做解释,需要自己脑补一下(╮(╯▽╰)╭)…

2024年大屏幕互动源码+动态背景图和配乐素材+搭建教程

2024年大屏幕互动源码动态背景图和配乐素材搭建教程 php宝塔搭建部署活动现场大屏幕互动系统php源码 运行环境:PHPMYSQL 下载源码地址:极速云

数据库设计:实体关系图

一个良好的设计对于数据库系统至关重要,它可以减少数据冗余,确保数据的一致性和完整性,同时使得数据库易于维护和扩展。 实体关系图(Entity-Relationship Diagram、ERD)是一种用于数据库设计的结构图,它描…

Webrtc支持HEVC之FFMPEG支持HEVC编解码(一)

一、前言 Webrtc使用的FFMPEG(webrtc\src\third_party\ffmpeg)和官方的不太一样,使用GN编译,各个平台使用了不一样的配置文件 以Windows为例,Chrome浏览器也类似 二、修改配置文件 windows:chromium\config\Chrome\win\x64 其他平台: chromium\config\Chrome\YOUR_SYS…

ARM32开发——第一盏灯

🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 开发流程需求分析项目新建代码编写GPIO初始化 程序编译程序烧录烧录扩展(熟悉)官方烧录器烧录(…

一份不知道哪里来的第十五届国赛模拟题

这是一个不知道来源的模拟题目,没有完全完成,只作代码记录,不作分析和展示,极其冗长,但里面有长按短按双击的复合,可以看看。 目录 题目代码底层驱动主程序核心代码关键:双击单击长按复合代码 …

今日学会的,刘姥姥进大观园

Git - First-Time Git Setup 下载了Git,会用Git了? 还有这个:学习 HTML5 Canvas 这一篇文章就够了 | 菜鸟教程 (runoob.com) JavaScript 用法 | 菜鸟教程 (runoob.com) 看到这个真的是受益匪浅,我终于懂了一直有的疑惑。 3D可…

RAG技术探索

什么是RAG 1 RAG原理 RAG(Retrieval Augmented Generation, 检索增强生成),即LLM在回答问题或生成文本时,先会从大量文档中检索出相关的信息,然后基于这些信息生成回答或文本,从而提高预测质量。RAG模型尤…

数据在内存中的存储<C语言>

导言 在计算机中不同类型的数据在计算机内部存储形式各不相同,弄懂各种数据在计算机内部存储形式是有必要的,C语言的学习不能浮于表面,更要锻炼我们的“内功”,将来在写程序的时候遇见各种稀奇古怪的bug时,也便能迎刃而…

控制障碍函数CBF详解(附带案例实现)

控制障碍函数CBF详解(附带案例实现) 文章目录 控制障碍函数CBF详解(附带案例实现)1. Control Affine System2. Lyapunov Theory, Nagumos Theory, Invariance Principle3. Control Lyapunov Function (CLF) and CLF-QP4. Control …

算法(十二)分治算法

文章目录 算法概念算法例子字符串中小写转大写求X^n问题 算法概念 分治算法(divide and conquer)算法的核心思想其实就是"分而治之",将原问题划分成n个规模较小,并且结构与原问题相似的子问题,递归地解决这…

移植其他命令行Vivado IDE的工具

移植其他命令行Vivado IDE的工具 介绍 本章介绍如何迁移各种AMD命令行工具以在AMD中使用 Vivado™集成设计环境(IDE)。 迁移ISE Partgen命令行工具 ISE™Design Suite Partgen工具可获得: •系统上安装的所有设备的信息 •详细的包装信息 您可…

[openwrt-21.02]openwrt-21.02 make menuconfig不显示luci-app-firewall问题分析及解决方案

问题描述 make menuconfig在 在applications界面没有luci-app-firewall 问题分析 首先重新执行 ./scripts/feeds update -a ./scripts/feeds install -a 然后再次执行make menuconfig,依然不显示,所以不是feeds安装的问题 最后看到log有个openmptc…

记录mabatis-plus初体验

一、简介 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found) 测试问题现象:测试mabatis的crud方法 增加 批量删除都没有问题 单单就是这个根据ID删除有问题 解决方案:真的就是pom文件的问题 自己的版本是Intelli…

Fully Convolutional Networks for Semantic Segmentation--论文笔记

论文笔记 资料 1.代码地址 2.论文地址 https://arxiv.org/abs/1411.4038 3.数据集地址 论文摘要的翻译 卷积网络是强大的视觉模型,可以产生特征层次结构。我们表明,卷积网络本身,经过端到端,像素对像素的训练,在…

【新能源大巴BMS结构与乘用车的区别】

新能源大巴BMS结构与乘用车的区别 这篇文章主要介绍新能源大巴的电池和BMS的结构与乘用车的区别。 主要有,新能源大巴行业、新能源电池系统结构和新能源大巴的BMS系统。 第一部分 新能源大巴行业 其实数数全球的商用车(大巴卡车),大致的方向还是沿着就…