数据结构------栈(Stack)和队列(Queue)

也是好久没写博客了,那今天就回归一下,写一篇数据结构的博客吧。今天要写的是栈和队列,也是数据结构中比较基础的知识。那么下面开始今天要写的博客了。

目录

栈(Stack)

队列(Queue)

喜欢就点个赞吧。


栈(Stack)

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除 操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out) 的原则。

 

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。

出栈:栈的删除操作叫做出栈。出数据也在栈顶。

简单描述栈的特点:栈数据的增删都是在一头进行,即在栈顶


那栈又该如何创建与使用呢?他的原理又是怎样的,这里我们就用C语言实现一下。

我们这里就要想这个栈是要用数组来实现还是用链表来实现呢?其实我们可以从其功能开始思考,这两者哪个更好去实现栈的功能,而且效率较高,其实说到这里,很多人可能已经有了结果,其实要说简洁与效率数组更适合来做栈。那么我们下面就来完成一下这个代码完成一个栈。

这里先给头文件因为其中有typedef来命名的类型,以免各位佬看得迷惑。

头文件

这里解释一下DataType是各位做栈时储存数据的类型,需要改变时只需要在头文件里改动一下即可,例如你想变成char类型的数据,即可将typedef int DataType; 改为 typedef char DataType;
然后栈的结构体我们就用ST来简化方便写代码。

然后top为栈的数据个数,capacity就表示栈的容量
 

#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
typedef int DataType;typedef struct Stack
{DataType* a;int top;int capacity;}ST;void StackInit(ST* ps);
void StackDestory(ST* ps);
// 入栈
void StackPush(ST* ps, DataType x);
// 出栈
void StackPop(ST* ps);
DataType StackTop(ST* ps);int StackSize(ST* ps);
bool StackEmpty(ST* ps);

 

栈的格式化

void StackInit(ST* ps)
{assret(ps);ps->a = (DataType)mallco(4 * (sizeof(DataType)));if (ps->a == NULL){printf("malloc fail\n");exit(-1);}ps->capacity = 4;ps->top = 0;}

先将数组a  mallco出四个数据的大小,然后将容量capacity改为4.


栈的销毁

void StackDestory(ST* ps){assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;}

使用完栈后进行销毁得函数,防止内存泄露。 及时free掉,然后将a指向NULL。


入栈 

void StackPush(ST* ps, DataType x)
{assert(ps);if (ps->top == ps->capacity){DataType* tem = (DataType*)recalloc(ps->a, 2*ps->capacity*sizeof(DataType));if (tem == NULL){printf("racallco fail\n");}else{ps->a = tem;ps->capacity = 2 * ps->capacity;}}ps->a[ps->top] = x;ps->top++;}

第一个if,先判断数组a是否还有空间入栈,如果满了就进行recallco增容即可增容我们现在时增容两倍较为合适,recallco的用法在前面动态内存创建的文章已经讲过了。所以现在就不多解释了。入栈后记得将top++一下 。


出栈

void StackPop(ST* ps)
{assert(ps);assert(ps->top > 0);ps->top--;
}

这里就比较简单粗暴将top--,即可将原本栈顶得书局给屏蔽即可。


求栈的长度和判断栈是否为空 

int StackSize(ST* ps)
{assert(ps);return ps->top;
}bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

 

接下来我们就来看看队列


队列(Queue)

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先 进先出FIFO(First In First Out)

 

队列的特点:队列与栈的不同是他是在一头进行增数据,一头删数据,而栈数据的增删都是在一头。

 然后我们思考一下队列的功能实现是要数组好还是链表好呢,这么一想是不是马上就发现了,如果们还是用数组来实现的话,那么其出队列的时间复杂度为O(N),那么效率太低了,而链表实现的话则是O(1),显而易队列还是用链表实现较好。


下面就是队列函数的实现了。

还是先给大家看看头文件

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>typedef int Type;typedef struct Queuenode 
{Type* date;struct Queue* next;}Node;typedef struct Queue
{Node* head;Node* tail;
}Queue;void QueueInit(Queue* pq);
void QueueDestory(Queue* pq);// 队尾入
void QueuePush(Queue* pq, Type x);
// 队头出
void QueuePop(Queue* pq);

这里解释一下为什么创建了两个结构体 ,因为其中一个作为链表的节点而另一个队列结构体。队列的结构体我们只需要要一个队头和队尾。


 队列的格式化

 

void QueueInit(Queue* pq)
{assert(pq);pq->head = NULL;pq->tail = NULL;}

很简单将队头和队尾指向空NULL即可。


队列的销毁

void QueueDestory(Queue* pq)
{assert(pq);Node* cur = pq->head;while (cur){Node* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;}

 这里我们运用一个while循环,创建一个辅助指针来保存节点的下一个。不断free 掉即可。

注意要将队头和队尾指空NULL。


进队

 

void QueuePush(Queue* pq, Type x)
{assert(pq);Node* new = (Node*)mallco(sizeof(Node));if (new == NULL){printf("mallco fail\n");}new->date = x;new->next = NULL;if (pq->tail = NULL){pq->tail = new;pq->head = new;}else{pq->tail->next = new;pq->tail = new;}}

 我们mallco一个空间,作为进队的一个节点,然后对节点进行赋值,然后对链表进行尾插就完成了一半了。

需要注意的是记得把原来的tail的next 指向新节点,也要把tail改为 新节点,因为尾插后new就为最后的节点也就是尾了。注意当前有没有节点那将head和tail至为new即可。


出队

void QueuePop(Queue* pq)
{assert(pq);assert(pq->head);if (pq->head->next == NULL){free(pq->head);pq->head = NULL;pq->tail = NULL;}Node* next = pq->head->next;free(pq->head);pq->head = next;}

 这里也是根据队列的删数据特点,这里的出队就是头删了,我们先把head的next保存住,然后free掉head,再然后让next作为新的头。

 


 今天就结束了,希望您能喜欢这篇文章。

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

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

相关文章

c++之旅——第一弹

本篇文章内容为C语言到C语言的过渡阶段第一篇&#xff0c;用来更好地过渡到c阶段&#xff0c;所以没有讲和C语言相同的知识点&#xff0c;着重于两者之间的区别之处来进行讲述c&#xff0c;创作不易&#xff0c;希望大家多多支持哦&#xff0c;如有知识性错误欢迎评论指正&…

P沟道与N沟道MOSFET的基本概念

N沟道与P沟道MOSFET基本原理与区别 学习MOSFET时的简单笔记作为个人总结&#xff0c;仅供学习参考&#xff0c;实际电路设计请直接略过&#xff01;&#xff01;&#xff01; 文章目录 N沟道与P沟道MOSFET基本原理与区别前言一、MOSFET &#xff1f;二、N沟道MOS管原理三、P沟…

网络编程day2

1.思维导图 2.TCP通信模型 tcpSer.c #include<myhead.h> #define SER_IP "192.168.159.143" #define SER_PORT 5678 int main(int argc, const char *argv[]) {//&#xff11;&#xff0e;创建用于监听的套接字int sfd-1;sfdsocket(AF_INET,SOCK_STREAM,0);/…

华为自动驾驶技术详解报告分享

ADS2.0首发搭载问界M5智驾版&#xff0c;城市NCA计划年底全国开通。2023年4月16日华为在智能汽车解决方案发布会上发布了最新的ADS2.0产品&#xff0c;硬件数量减少至27个(11个摄像头12个超声波雷达3个毫米波雷达1个激光雷达,ADS1.0有34个)&#xff0c;车载计算平台改为MDC610&…

二叉树——二叉树所有路径

二叉树所有路径 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,null,5] 输出&#xff1a;["1->2->5","1-…

深入理解Java中的优先级队列(堆)——PriorityQueue

引言&#xff1a; 在Java中&#xff0c;优先级队列&#xff08;PriorityQueue&#xff09;是一种基于堆结构实现的队列&#xff0c;其中每个元素都有一个优先级&#xff0c;优先级高的元素在队列中具有更高的优先级&#xff0c;排在前面。优先级队列常用于任务调度、事件处理等…

9.函数,变量作用域(全局作用域和局部作用域),匿名函数,立即执行函数,逻辑中断,常见值布尔判断

函数 其实学习函数学习的不仅仅是在js中如何声明一个函数如何给函数传参如何引用和调用函数&#xff0c;函数在整个编程领域都是一种思想—抽取和封装的思想 那么啥是抽取和封装的思想呢&#xff1f;-------------------------------------------- 抽取 抽取就是比如拿厨房…

【MATLAB源码-第149期】基于MATLAB的2ASK,2FSK,2PSK,2DPSK等相干解调仿真,输出各节点波形。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 2ASK&#xff08;二进制幅移键控&#xff09;、2FSK&#xff08;二进制频移键控&#xff09;、2PSK&#xff08;二进制相移键控&#xff09;和2DPSK&#xff08;二进制差分相移键控&#xff09;是数字调制技术中的基本调制方…

1 数据分析概述与职业操守

1、 EDIT数字化模型 E——exploration探索 &#xff08;是什么&#xff09; 业务运行探索&#xff1a;探索关注企业各项业务的运行状态、各项指标是否合规以及各项业务的具体数据情况等。 指标体系——目标&#xff08;O&#xff09;、策略&#xff08;S&#xff09;、指标&a…

网工内推 | 项目经理,软考证书优先,最高26K,加班补贴

01 龙盈智达 招聘岗位&#xff1a;项目经理 职责描述&#xff1a; 1 根据业务员需求&#xff0c;完成生态圈下账簿中心系统的开发管理工作。 2 负责账簿中心实施过程中的需求调研分析、方案设计、开发测试、系统上线等工作的计划、组织协调、沟通等方面管理工作。 3 完成系统核…

将python程序打包为exe格式

1. 安装pyinstaller winr打开命令窗口 输入&#xff1a; pip install pyinstaller输入命令后会自动安装pyinstaller 2. 打包 进入你的代码所在位置&#xff0c;输入cmd 在弹出的窗口中输入 pyinstaller --onefile your_script.pyyour_script.py修改为你需要打包的程序名字 …

select * from 表 c=‘1‘ and b=‘2‘ and a=‘3‘; abc是联合索引,这样查询会命中索引吗?

倒叙也会命中索引 但是要注意&#xff0c;倒叙的时候必须要有a存在&#xff0c;否则就会索引失效 因为mysql底层会有优化器去进行优化&#xff0c;但是如果没有a的话&#xff0c;那么优化器就不知道要优化那个索引了&#xff0c;所以他走了全表&#xff0c;导致索引失效