当前位置: 首页 > news >正文

初步认识栈和队列

Hello,everyone,今天小编讲解栈和队列的知识!!!

1.栈

1.1栈的概念及结构

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

1.2栈的实现

栈的实现一般可以使用 数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。

4989397040924c16ae4cee9cde928b58.pngceeed439a06943b3b425c53438865c60.png1.2.1 头文件的建立

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef  int  datatype;
//这里选用动态数组实现栈,单链表也可以
typedef struct stack {datatype* a;int top;//栈顶int capacity;
}ST;
//栈的初始化和销毁
void STInit(ST* pst);
void STDestory(ST* pst);
//入栈和出栈
void STPush(ST* pst,datatype x);
void STPop(ST* pst);
//获取栈顶数据
datatype STTop(ST* pst);
//判空
bool STEmpty(ST* pst);
//栈的数据个数
int STSize(ST* pst);

1.2.2 函数的实现

#define _CRT_SECURE_NO_WARNINGS
#include "Stack.h"
//栈的初始化和销毁
void STInit(ST* pst){assert(pst);pst->a = NULL;//top指向栈顶数据的下一个位置,可以理解为下标pst->top = 0;//top指向指向栈顶数据,可以理解成栈的数据个数//pst->top=-1;pst->capacity = 0;
}
void STDestory(ST* pst) {assert(pst);free(pst);pst->a = NULL;pst->top = pst->capacity = 0;
}
//容量检查
void Checkcapacity(ST* pst) {assert(pst);if (pst->top == pst->capacity) {int newcapacity = pst->capacity==0?4:pst->capacity * 2;datatype* temp = (datatype*)realloc(pst->a, newcapacity * sizeof(datatype));if (temp == NULL) {perror("relloc fail");return;}pst->a = temp;pst->capacity = newcapacity;}
}
//入栈和出栈
void STPush(ST* pst, datatype x) {assert(pst);Checkcapacity(pst);pst->a[pst->top] = x;pst->top++;
}
void STPop(ST* pst) {assert(pst);assert(pst->top>0);pst->top--;
}
//获取栈顶数据
datatype STTop(ST* pst) {assert(pst);assert(pst->top > 0);return pst->a[pst->top-1];
}
//判空
bool STEmpty(ST* pst) {assert(pst);return pst->top == 0;//表达式判断
}
//栈的数据个数
int STSize(ST* pst) {assert(pst);return pst->top;
}

1.2.3 测试文件

#define _CRT_SECURE_NO_WARNINGS
#include "Stack.h"
int main() {ST s;STInit(&s);STPush(&s, 1);STPush(&s, 2);STPush(&s, 3);STPush(&s, 4);STPush(&s, 5);printf("%d\n", STTop(&s));STPop(&s);//STPop(&s);printf("%d\n", STTop(&s));while (!STEmpty(&s)) {printf("%d ", STTop(&s));STPop(&s);}STDestory(&s);return 0;
}

2.队列

2.1队列的概念及结构

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

2.2队列的实现

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
08baa117744c4aa2b522b9b638a7d8e8.png
695a5ab0f7a74c8b9ab0b32f9a961bb8.png

2.2.1 头文件的建立

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
typedef int Qdatatype;
//链式结构表示队列
typedef struct QueueNode {struct QueueNode* next;Qdatatype x;
}Node;
//定义结构体表示队头队尾,后续传参改变队列也很方便,不用传二级指针。
typedef struct Queue {Node* head;Node* tail;int size;
}Queue;
// 初始化队列
void QueueInit(Queue* q);// 队尾入队列
void QueuePush(Queue* q, Qdatatype data);// 队头出队列
void QueuePop(Queue* q);// 获取队列头部元素
Qdatatype QueueFront(Queue* q);// 获取队列队尾元素
Qdatatype QueueBack(Queue* q);// 获取队列中有效元素个数
int QueueSize(Queue* q);// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q);// 销毁队列
void QueueDestroy(Queue* q);

2.2.2  函数的实现

#define _CRT_SECURE_NO_WARNINGS
#include "Queue.h"
void QueueInit(Queue* q) {assert(q);q->head = NULL;q->tail = NULL;q->size = 0;
}
// 队尾入队列
void QueuePush(Queue* q, Qdatatype data) {assert(q);Node* newnode = (Node*)malloc(sizeof(Node));if (newnode == NULL) {perror("malloc fail");return;}newnode->next = NULL;newnode->x = data;if (q->tail ==NULL) {q->head = q->tail = newnode;}else {q->tail->next = newnode;q->tail = newnode;}q->size++;
}
// 队头出队列
void QueuePop(Queue* q) {assert(q);assert(q->size != 0);//一个节点if (q->head->next == NULL) {free(q->head);q->head = q->tail = NULL;}else {Node* next = q->head->next;free(q->head);q->head = next;}q->size--;
}
// 获取队列头部元素
Qdatatype QueueFront(Queue* q) {assert(q);assert(q->head);return q->head->x;
}
// 获取队列队尾元素
Qdatatype QueueBack(Queue* q) {assert(q);assert(q->tail);return q->tail->x;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q) {assert(q);return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q) {assert(q);return q->size == 0;//为0,返回1,不为0,返回0;
}
// 销毁队列
void QueueDestroy(Queue* q) {assert(q);Node* qcur = q->head;while (qcur) {Node* next = qcur->next;free(qcur);qcur = next;}q->head = q->tail = NULL;q->size = 0;
}

2.2.3  测试文件

#define _CRT_SECURE_NO_WARNINGS
#include "Queue.h"
int main() {Queue p;QueueInit(&p);QueuePush(&p,1);QueuePush(&p,2);printf("%d\n", QueueFront(&p));QueuePush(&p, 3);QueuePush(&p, 4);printf("%d\n",QueueBack(&p));QueuePop(&p);printf("%d\n", QueueFront(&p));while (!QueueEmpty(&p)){printf("%d ", QueueFront(&p));QueuePop(&p);}printf("\n");return 0;
}
另外扩展了解一下,实际中我们有时还会使用一种队列叫循环队列。如操作系统讲解生产者消费者模型时可以就会使用循环队列。环形队列可以使用数组实现,也可以使用循环链表实现。
adf81511000b4a73a28cca90fa8f2109.png
今天内容讲解结束,下次小编将讲解栈和队列的相关习题。
希望各位友友留下三连和评论!!!

 

相关文章:

  • 网络安全等级保护:正确配置 Linux
  • 38、Flink 的窗口触发器(Triggers)详解
  • html5网页-浏览器中实现高德地图定位功能
  • 生产制造边角料核算说明及ODOO演示
  • Adobe Bridge BR v14.0.3 安装教程 (多媒体文件组织管理工具)
  • LabelMe下载及关键点检测数据标注
  • 【全开源】海报在线制作系统源码(ThinkPHP+FastAdmin+UniApp)
  • STM32手写超频到128M函数
  • 嵌入式0基础开始学习 ⅠC语言(7)指针
  • 2024年全国大学生电工数学建模竞赛B题解析 | 数据处理 代码 论文分享
  • Kiwi浏览器 - 支持 Chrome 扩展的安卓浏览器
  • Vue3解决“找不到模块“@/components/xxx.vue”或其相应的类型声明”
  • Docker: exec命令浅析
  • Java核心: 脚本引擎和动态编译
  • 三种路由协议RIP,OSPF和BGP
  • (三)从jvm层面了解线程的启动和停止
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • javascript 总结(常用工具类的封装)
  • java小心机(3)| 浅析finalize()
  • Laravel 菜鸟晋级之路
  • Material Design
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Python学习笔记 字符串拼接
  • Vultr 教程目录
  • 浮动相关
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 看域名解析域名安全对SEO的影响
  • 模型微调
  • 入门级的git使用指北
  • 问题之ssh中Host key verification failed的解决
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 因为阿里,他们成了“杭漂”
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • #java学习笔记(面向对象)----(未完结)
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (09)Hive——CTE 公共表达式
  • (C语言)fgets与fputs函数详解
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (四)JPA - JQPL 实现增删改查
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • .NET 表达式计算:Expression Evaluator
  • .NET(C#) Internals: as a developer, .net framework in my eyes
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .NET8使用VS2022打包Docker镜像
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • //TODO 注释的作用
  • @Autowired @Resource @Qualifier的区别
  • @component注解的分类