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

数据结构 - 栈和队列

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

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);
}

相关文章:

  • lua与C++粘合层框架
  • Clickhouse表引擎介绍
  • ARM单片机中程序在ROM空间和RAM空间的分布(分散加载文件,Scatter-Loading Description File)
  • Humanoid-Gym 开源人形机器人端到端强化学习训练框架!星动纪元联合清华大学、上海期智研究院发布!
  • 产品推荐 - 基于6U VPX的双TMS320C6678+Xilinx FPGA K7 XC7K420T的图像信号处理板
  • ORACLE基于归档号增量恢复
  • windows关闭copilot预览版
  • 分布式定时任务调度xxl-job
  • ElevenLabs用AI为Sora文生视频模型配音 ,景联文科技提供高质量真人音频数据集助力生成逼真音效
  • HTML—常用标签
  • Rust 语言的 async 关键字
  • Linux系统——Haproxy高性能负载均衡软件
  • 初阶数据结构之---二叉树的顺序结构-堆
  • 网站被插入虚假恶意链接怎么办?
  • 微软AI工程师向联邦贸易委员会(FTC)发出警告,对Copilot Designer的安全性表示担忧
  • 2019.2.20 c++ 知识梳理
  • Angular4 模板式表单用法以及验证
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • Idea+maven+scala构建包并在spark on yarn 运行
  • Intervention/image 图片处理扩展包的安装和使用
  • JavaScript标准库系列——Math对象和Date对象(二)
  • Next.js之基础概念(二)
  • Node 版本管理
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • Objective-C 中关联引用的概念
  • October CMS - 快速入门 9 Images And Galleries
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 给github项目添加CI badge
  • 记录:CentOS7.2配置LNMP环境记录
  • 简单实现一个textarea自适应高度
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 我的面试准备过程--容器(更新中)
  • 我建了一个叫Hello World的项目
  • 新书推荐|Windows黑客编程技术详解
  • 怎样选择前端框架
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • # Apache SeaTunnel 究竟是什么?
  • #Java第九次作业--输入输出流和文件操作
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (八十八)VFL语言初步 - 实现布局
  • (差分)胡桃爱原石
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • (一)80c52学习之旅-起始篇
  • (一)Linux+Windows下安装ffmpeg
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'