栈和队列知识点+例题

1.栈

1.1栈的概念及结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素的操作。进行数据插入和删除操作的一端成为栈顶,另一端成为栈底。遵守后进先出的原则(类似于弹夹)

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

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

那如何实现栈呢?

 经过比较,数组栈是最优解,(链式的扩容会很久才会扩容一下)

由于top的位置意义不同,我们分为两种解决方案

1.2基本操作 

1.定义一个栈

typedef int SLDataType;
typedef struct Stack
{int *a;int top;int capacity;
}

2,初始化一个栈

void STInit(ST*pst)
{assert(pst);pst->a=NULL;pst->top=0;pst->capacity=0;
}

3压栈

void STPush(ST* pst, SLDataType x)
{assert(pst);if (pst->top == pst->capacity){ST* newcapacity = pst->capacity == 0 ? 4 : capacity * 2;SLDataType* tmp = (SLDataType*)realloc((SLDataType)*newcapacity);if (newcapacity == NULL){return -1;}else{pst->a = tmp;pst->capacity = newcapacity;pst->a[pst->top] = x;pst->top++;}}
}

 4,弹栈

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

5 返回栈顶元素

void STTop(ST* pst)
{assert(pst);assert(pst->top>0);return pst->a[pst->top-1];
}

6 判断是否为空

bool STEmpty(ST* pst)
{assert(pst);if (pst->top == 0){return true;}else{return false;}
}

7 栈的大小

int STSize(ST* pst)
{assert(pst);return pst->top;
}

8销毁栈

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

让我们看几道例题吧

例题1:

 思路:栈的顺序是后进先出,有题可知,最后一个是E,所以E先出,故选B

例题2:

 我们首先看选项,A选项:1先进,1先出,把2 3 4放进去,把4拿出来,再把3拿出来,最后把2拿出来。同理,我们看C选项,把1 2 3放进去,然后把3拿出来,然后我们会发现,如果想要拿1的话,拿2是必经之路,所以此选项错误

例题3:

 思路:

1,先建立一个栈,初始化一个栈,

2,然后我们把所有的左括号放入栈里面,如果不是左括号,即是有括号;

3,其次我们要知道,本题的关键在于数量匹配和顺序匹配。所以我们要考虑一下栈是否为空(右括号的数量大于左括号的数量),然后考虑顺序匹配的问题

4,最后我们看栈是否为空,如果为空,就返回true,然后把栈毁掉

bool isVaild(char* s)
{ST st;// 定义一个栈STInit(&st);while (*s){if (*s == '[' || *s == '{' || *s == '('){STPush(&st, *s);s++;}else{if (STEmpty(&st)){return false;}//栈里面取左括号char top = STTop(&st);STPop(&st);//顺序不匹配if (*s == ']' && top != '[') || (8s == '}' && top != '{') || (*s == ')' && top == '('){return false;}s++;}}//栈为空,返回真,说明数量都匹配bool ret = STEmpty(&st);STDestory(&pst);return ret;
}

好啦~栈我们就先讲到这里啦,让我们看一下队列的知识点吧

2,队列

2.1队列的概念和结构

 我们可以考虑一个问题

入队之后,出队的时候顺序是唯一一定的吗?

答案是:当然是;

从以上我们可以了解到,栈用数组的方法比较好;而队列用单链表,头删尾插的方式比较好

2.2基本操作

1定义一个队列

typedef int QueueType;
typedef struct QueueNode
{QueueType val;struct QueueNode* next;}QNode;

为了解决二级指针以及两个指针的问题,我们可以把两个指针放入一个结构体里面,然后进行一级指针的操作即可

typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;

2.初始化一个队列

void QueueInit(Queue* pq)
{assert(pq);pq->size = 0;pq->phead = pq->ptail = NULL;
}

3.插入到队列

	void QueuePush(Queue* pq, QDataType x){QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL)return -1;else{newnode->val = x;newnode->next = NULL;}if (pq->tail == NULL){return -1;pq->tail = pq->phead = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;}

4. 头删

void QueuePop(Queue* pq)
{assert(pq);assert(pq->phead);QNode* del = pq->phead;pq->phead = pq->phead->next;if (pq->phead = NULL)pq->tail = NULL;
}

5找头结点的值

QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->phead);return pq->phead->val;
}

6队列是否为空

bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead=NULL;
}

7队列大小

int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}

8销毁队列

void QueueDestory(Queue* pq)
{assert(pq);QNode* cur = pq->phead;while (cur){QNode* next = cur->next;cur = next;}
pq->phead=pq->ptail=NULL;
}

让我们看几道关于队列和栈的例题吧

例题1:

思路: 

 代码实现:

typedef struct
{Queue q1;Queue q2;}Stack;MyStack* CreateStack()
{MyStack* pst = (MyStack*)malloc(sizeof(MyStack));QueueInit(&pst->q1);QueueInit(&pst->q2);return pst;
}
void mystackpush(Mystack* obj, int x)
{Queue Empty = &obj->q1;Queue nonEmpty =&obj->q2;if (!Empty(&obj->q1)){Queue Empty = &obj->q2;Queue nonEmpty = &obj->q1;}//开始到数据while (QueueSize(nonempty) > 1){QueuePush(Empty, QueueFront(nonempty));QueuePop(nonempty);}int top = QueueFront(nonempty);QueuePop(nonempty);return top;
}int mystackTop(Mystack* obj)
{if (!Empty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}
}
bool mystackEmpty(MyStack* obj)
{return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void mystackFree(Mystack* obj)
{QueueDestory(&obj->q1);QueueDestory(&obj->q2);free(obj);
}

例题2:

 

 思路:

 代码实现:

 

typedef struct
{int* a;int top;int capacity;
}ST;
typedef struct
{ST pushst;ST popst;
}MyQueue;
//初始化
void STInit(ST* pst)
{assert(pst);pst->a = NULL;pst->top = 0;pst->capacity = 0;
}
//压栈
void STPush(ST* pst, SLDataType x)
{assert(pst);if (pst->top == pst->capacity){ST* newcapacity = (SLDataType*)malloc(sizeof(SLDataType);SLDataType* tmp = pst->capacity == 0 ? 4 : newcapacity * 2;if (newcapacity == 0){return -1;}else{pst->a = tmp;pst->capacity = newcapacity;pst->a[pst->top] = x;pst->top++;}}
}
//返回栈顶元素
void STTop(ST* pst)
{assert(pst);assert(pst->top > 0);return pst->a[pst->top - 1];
}
//弹栈
void STPop(ST* pst)
{assert(pst);assert(pst->top > 0);pst->top--;
}
//判断是否为空
bool STEmpty(ST* pst)
{assert(pst);if (pst->top == 0){return true;}else{return -1;}
}
MyQueue* myQueueCreate()
{MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));STInit(&obj->pushst);STInit(&obj->popst);return obj;
}
void myQueuePush(MyQueue* obj, int x)
{STPush(&obj->pushst, x);
}
返回队列开头的元素(不删除)
void myQueuepeek(MyQueue* obj)
{if (!STEmpty(&obj->popst)){return STTop(&obj->popst);}else{while (!STEmpty(&obj->pushst)){STPush(&obj->popst, STTop(&obj->pushst);STPop(&obj->pushst);}return STTop(&obj->popst);}
}
//从队列开头移除并返回元素
void myQueuePop(MyQueue* obj)
{int front = myQueuePeek(obj);STPop(&obj->popst);return front;
}
bool myQueueEmpty(MyQueue* obj)
{return  STEmpty(&obj->pushst) && (&obj->popst);
}
void myQueueFree(MyQueue* obj)
{STDestory(&obj->popst);STDestory(&obj->pushst);free(obj);
}

接下来我们看一下循环队列吧

1.判断循环队列是否为空:front==back(front指向对头,back指向队尾的下一个)

 

 如何判断队列是否为满

1.前提:front==back(当size=0时,为空,size!=0则为满)

2,再增加一个地方)

数组实现(back+1)%(k+1)==front则为满,其中,k+1指的是开辟空间的个数,k指的是有效数据数 数组实现&(k+1)是为了防止溢出

链表实现,即把上面式子去掉  %(k+1)

链表实现:

 

 数组实现:

 单链表缺陷以及找尾的办法:

 如何计算循环中元素的个数

typedef struct {int* a;int front;int back;int k;
}MyCircularQueue;
//初始化
MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));obj->a = (int*)malloc(sizeof(int) * (k + 1));obj->front = 0;obj->back = 0;obj->k = 0;return obj;
}
//是否为空
bool myCircularQueueEmpty(MyCircularQueue* obj)
{return obj->front = obj - back;}
//是否为满
bool myCircularQueueIsFull(MyCircularQueue* obj)
{return (obj->front) % (obj->k + 1) == obj->front;}
//插入
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{if (myCircularQueueIsFull(obj)){return false;}obj->a[obj->back] = value;obj->back++;obj->back % (obj->k + 1) = obj->back;return true;
}
//删除
bool myCircularQueueDeQueue(MyCircularQueue* obj, int value)
{if (myCircularQueueIsFull(obj)){return false;}++obj->front;obj->front % (obj->k + 1) = obj->front;return true;
}
//返回队头
int myCircularQueueFront(MyCircularQueue* obj)
{if (myCircularQueueIsFull(obj)){return false;}return obj->a[obj->front];
}
//返回队尾
int myCircularQueueRear(MyCircularQueue* obj)
{if (myCircularQueueIsFull(obj)){return false;}return obj->a[obj->back - 1];
}
//清空
void myCircularQueueFree(MyCircularQueue* obj)
{free(obj->a);free(obj);
}

好啦~关于栈和队列的知识点就这些啦~谢谢大家观看~

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

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

相关文章

一文讲明 网络调试助手的基本使用 NetAssist

我 | 在这里 🕵️ 读书 | 长沙 ⭐软件工程 ⭐ 本科 🏠 工作 | 广州 ⭐ Java 全栈开发(软件工程师) 🎃 爱好 | 研究技术、旅游、阅读、运动、喜欢流行歌曲 🏷️ 标签 | 男 自律狂人 目标明确 责任心强 ✈️公…

实战 - 在Linux上部署各类软件

前言 为什么学习各类软件在Linux上的部署 在前面,我们学习了许多的Linux命令和高级技巧,这些知识点比较零散,同学们跟随着课程的内容进行练习虽然可以基础掌握这些命令和技巧的使用,但是并没有一些具体的实操能够串联起来这些知…

Ubuntu18.04安装Moveit框架

简介 Moveit是一个由一系列移动操作的功能包组成的集成化开发平台,提供友好的GUI,是目前ROS社区中使用度排名前三的功能包,Moveit包含以下三大核心功能,并集成了大量的优秀算法接口: 运动学:KDL,Trac-IK,IKFast...路径规划:OMPL,CHMOP,SBPL..碰撞检测:FCL,PCD... 一、更新功…

全球地表水年度数据集JRC Yearly Water Classification History, v1.4数据集

简介: JRC Yearly Water Classification History, v1.4是一个对全球水资源进行分类的数据集,覆盖了1984年至2019年的时间范围。该数据集是由欧盟联合研究中心(JRC)开发的,使用的数据源是来自Landsat系列卫星的高分辨率…

十. Linux关机重启命令与Vim编辑的使用

关机重启命令 shutdown命令 其他关机命令 其他重启命令 系统运行级别 系统默认运行级别与查询 退出登录命令logout 文本编辑器Vim Vim简介 没有菜单,只有命令Vim工作模式 Vim常用命令 插入命令 定位命令 删除命令 复制和剪切命令 替换和取消命令 搜索和搜索替换命令 保存和退出…

毅速丨嫁接打印在模具制造中应用广泛

在模具行业中,3D打印随形水路已经被广泛认可,它可以提高冷却效率,从而提高产品良率。然而,全打印模具制造的成本相对较高,因为需要使用金属3D打印机和专用材料。为了节省打印成本,同时利用3D打印的优势&…

【Python】问题描述:输入A、B,输出A+B。样例输入12 45样例输出57

1、问题描述 输入A、B,输出AB。 样例输入 12 45 样例输出 57 nums list(map(int,input().split(" "))) print(sum(nums))

STM32 Flash

FLASH简介 Flash是常用的用于存储数据的半导体器件,它具有容量大,可重复擦写,按“扇区/块”擦除、掉电后数据可继续保存的特性。 常见的FLASH主要有NOR FLASH和NAND FLASH两种类型。NOR和NAND是两种数字门电路,可以简单地认为FL…

Haclon案例-找出图中面积最大的圆

任务描述: 下图为HALCON自带的“brake_disk_part_01.png”的图片,试着给它加上不同种类的噪声,然后找出其中面积最大的圆,并将圆的面积标注在其圆心位置。 案例剖析: 1. 该图片为一灰度图,对其进行二值化…

【ctfshow】web入门-信息搜集-web21~28

SSS web21_爆破什么的,都是基操web22_域名也可以爆破的,试试爆破这个ctf.show的子域名web23_还爆破?这么多代码,告辞!web24_爆个🔨web25_爆个🔨,不爆了web26_这个可以爆web27_CTFsho…

[格式化字符串漏洞+堆溢出] Suctf2019_sudrv

前言 悲悲悲, 晚上5点 os-lab 实验报告 ddl, 早上肝实验报告肝到一半, 然后抽风想去做一道 kernel pwn. 然后在一个地方卡了半个多小时, 结果就是写这个 post 的时候已经两点了, 悲. 漏洞分析 这题算是一个入门题, 哎, 就是我在泄漏 kernel offset 的时候想一步到位, 结果就…

存储配置和挂载方式

存储配置 Iscsi简介 iSCSI 启动器,从本质上说,iSCSI 启动器是一个客户端设备,用于将请求连接并启动到服务器(iSCSI 目标)。 iSCSI 启动器有三种实现方式:可以完全基于硬件实现,比如 iSCSI H…

C++快速入门 - 2(几分钟让你快速入门C++)

C快速入门 - 2 1. 内联函数1.1 概念1.2 特性 2. auto关键字(C11)2.1 类型别名思考2.2 auto简介2.3 auto的使用细则2.4 auto不能推导的场景 3. 基于范围的for循环(C11)3.1 范围for的语法3.2 范围for的使用条件 1. 内联函数 1.1 概念 以inline修饰的函数叫做内联函数&#xff0c…

ceph学习笔记

ceph ceph osd lspoolsrbd ls -p testpool#查看 ceph 集群中有多少个 pool,并且每个 pool 容量及利 用情况 rados dfceph -sceph osd tree ceph dfceph versionsceph osd pool lsceph osd crush rule dumpceph auth print-key client.adminceph orch host lsceph crash lsceph…

常见树种(贵州省):008果树种类

摘要:本专栏树种介绍图片来源于PPBC中国植物图像库(下附网址),本文整理仅做交流学习使用,同时便于查找,如有侵权请联系删除。 图片网址:PPBC中国植物图像库——最大的植物分类图片库 一、苹果 …

白鳝:聊聊IvorySQL的Oracle兼容技术细节与实现原理

两年前听瀚高的一个朋友说他们要做一个开源数据库项目,基于PostgreSQL,主打与Oracle的兼容性,并且与PG社区版内核同步发布。当时我听了有点不太相信,瀚高的Highgo是在PG内核上增加了一定的Oracle兼容性的特性,一般也会…

基于springboot实现医院信管系统项目【项目源码+论文说明】

基于springboot实现医院信管系统演示 摘要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生&#x…

注解案例:山寨Junit与山寨JPA

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 上篇讲了什么是注解&am…

ros2机器人上位机与下位机连接方式(转载)

从硬件连接、通信协议和软件设计开发,上位机如何控制下位机? 由你创科技2023-09-07 10:38广东 随着科技的不断发展,自动化控制系统已经广泛应用于各个行业。在自动化控制系统中,上位机和下位机是两个重要的组成部分。上位机主要…

【漏洞复现】泛微E-Office信息泄露漏洞(CVE-2023-2766)

漏洞描述 Weaver E-Office是中国泛微科技(Weaver)公司的一个协同办公系统。 Weaver E-Office 9.5版本存在安全漏洞。攻击者利用该漏洞可以访问文件或目录。 影响版本 Weaver E-Office 9.5版本 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵…