当前位置: 首页 > 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);
}

相关文章:

数据结构 - 栈和队列

本篇博客将介绍栈和队列的定义以及实现。 1.栈的定义 栈是一种特殊的线性表,只允许在固定的一端进行插入和删除数据,插入数据的一端叫做栈顶,另一端叫做栈底。栈中的数据遵守后进先出的原则 LIFO (Last In First Out)。 插入数据的操作称为压…...

C++:模版进阶 | Priority_queue的模拟实现

创作不易,感谢三连支持 一、非类型模版参数 模板参数分类为类型形参与非类型形参。 类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。 非类型形参,就是用一个常量作为类(函数)模板的一个参数&…...

【刷题记录】详谈设计循环队列

下题目为个人的刷题记录,在本节博客中我将详细谈论设计循环队列的思路,并给出代码,有需要借鉴即可。 题目:LINK 循环队列是线性表吗?或者说循环队列是线性结构吗? 对于这个问题,我们来看一下线…...

人工智能|机器学习——k-近邻算法(KNN分类算法)

1.简介 k-最近邻算法,也称为 kNN 或 k-NN,是一种非参数、有监督的学习分类器,它使用邻近度对单个数据点的分组进行分类或预测。虽然它可以用于回归问题,但它通常用作分类算法,假设可以在彼此附近找到相似点。 对于分类…...

乐得瑞 1C to 2C快充线:引领充电数据线新潮流,高效快充解决接口难题

随着科技的不断进步,数据线的接口种类也日渐繁多,但在早些时候,三合一和二合一的数据线因其独特的设计而备受欢迎。这类数据线通常采用USB-A口作为输入端,并集成了Micro USB、Lightning以及USB-C三种接口,满足了当时市…...

O2OA(翱途)开发平台如何在流程表单中使用基于Vue的ElementUI组件?

本文主要介绍如何在O2OA中进行审批流程表单或者工作流表单设计,O2OA主要采用拖拽可视化开发的方式完成流程表单的设计和配置,不需要过多的代码编写,业务人员可以直接进行修改操作。 在流程表单设计界面,可以在左边的工具栏找到Ele…...

0 OpenHarmony开源鸿蒙NEXT星河版内核嵌入式编程

开源鸿蒙NEXT星河版内核嵌入式编程 作者将狼才鲸创建日期2024-03-08 CSDN文章阅读地址Gitee文章下载地址 一、前景提要 2024年1月18日,华为放出HarmonyOS NEXT 鸿蒙星河版开发者预览版本(不是HarmonyOS NEXT版,是HarmonyOS NEXT星河版&…...

Vue | 基于 vue-admin-template 项目的跨域问题解决方法

目录 一、现存问题 二、解决方法 2.1 修改的第一个地方 2.2 修改的第二个地方 2.3 修改的第三个地方 自存 一、现存问题 报错截图如下: 二、解决方法 2.1 修改的第一个地方 在 .env.development 文件中: # base api # VUE_APP_BASE_API /d…...

mutex 和 channel 哪一个工作效率更高?

关于Rust中mutex和channel哪一个工作效率更高的问题,实际上并没有一个绝对的答案,因为效率的高低取决于具体的使用场景和需求。 互斥锁(mutex)主要用于保护共享资源,确保一次只有一个线程可以访问它。当需要多个线程同…...

Elasticsearch 通过索引阻塞实现数据保护深入解析

Elasticsearch 是一种强大的搜索和分析引擎,被广泛用于各种应用中,以其强大的全文搜索能力而著称。 不过,在日常管理 Elasticsearch 时,我们经常需要对索引进行保护,以防止数据被意外修改或删除,特别是在进…...

备考银行科技岗刷题笔记(持续更新版)

银行考试计算机部分复习 IEEE 802.11的帧格式 1.1 IEEE 802.11是什么? 802.11是国际电工电子工程学会(IEEE)为无线局域网络制定的标准。目前在802.11的基础上开发出了802.11a、802.11b、802.11g、802.11n、802.11ac。并且为了保证802.11更…...

代码随想录算法训练营第五十五天|583. 两个字符串的删除操作、72. 编辑距离。

583. 两个字符串的删除操作 题目链接:两个字符串的删除操作 题目描述: 给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 解题思路: 1、确定dp数组&#x…...

Softmax 回归 + 损失函数 + 图片分类数据集【动手学深度学习v2】李沐动手学深度学习课程笔记

目录 Softmax回归 损失函数 图片分类数据集 Softmax回归从零开始实现 Softmax回归简洁实现 Softmax回归 回归和分类的区别 回归问题举例上节课的预测房价问题,分类问题就是对样本进行分类 回归和分类的具体区别 假设真实的类别为第i个类别(值为1&#x…...

git 初始化项目并上传到github

如果还没配置过,需要配置账号信息 git config --global user.name "baymax-collab" git config --global user.email "baymax-collabtest.com"创建一个新的存储库 git clone gitgithub.com:xxxx cd test git switch --create main touch READ…...

前端javascript的DOM对象操作技巧,全场景解析

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 所属的专栏:前端泛海 景天的主页:景天科技苑 文章目录 1.js的DOM介绍2.节点元素层级关系3.通过js修改,清空节点…...

TCP包头、TCP为什么安全可靠、UDP和TCP的区别、http协议

我要成为嵌入式高手之3月8日Linux高编第十八天!! __________________________________________________ 学习笔记 TPC包头 1、序号 发送端发送数据包的编号 2、确认号 已经确认接收到的数据的编号,只有当ACK为1时,该位才有用 …...

Android使用WebView打开内嵌H5网页

Android打开外部网页链接请参考上一篇文章 https://public.blog.csdn.net/article/details/136384559 继上篇,新建assets文章夹,将H5的网页资源放到此文件夹下 把H5的资源文件都拷进来 这个时候,将添加打开本地网页的代码: //打…...

UDP实现文件的发送、UDP实现全双工的聊天、TCP通信协议

我要成为嵌入式高手之3月7日Linux高编第十七天!! ———————————————————————————— 回顾 重要程序 1、UDP实现文件的发送 发端: #include "head.h"int main(void) {int sockfd 0;struct sockaddr_i…...

Yocto - Project Quick Build

欢迎光临! 这篇简短的文档将向您介绍使用 Yocto 项目构建典型镜像的过程。本文还介绍了如何为特定硬件配置构建。您将使用 Yocto Project 构建一个名为 Poky 的参考嵌入式操作系统。 Welcome! This short document steps you through the process for a typical i…...

深入探讨C++中的可变参数列表(Variadic Templates)

文章目录 导言可变参数列表的基本用法使用std::initializer_list应用场景 导言 在C编程中,处理可变数量参数的能力是一种非常有用的功能。通过可变参数列表,你可以编写更加通用和灵活的函数,从而提高代码的可读性和重用性。本文将详细介绍C中…...

Axure中文语言包:3分钟极速汉化指南,让原型设计更高效

Axure中文语言包:3分钟极速汉化指南,让原型设计更高效 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还…...

如何实现网盘全速下载:八大平台直链获取完整指南

如何实现网盘全速下载:八大平台直链获取完整指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 …...

Dify如何通过合规配置规避AI幻觉导致的销售误导?监管处罚案例倒推的4层校验机制

第一章:Dify如何通过合规配置规避AI幻觉导致的销售误导?监管处罚案例倒推的4层校验机制在金融、保险及SaaS销售场景中,AI生成话术若未经严格约束,极易因幻觉输出虚构产品条款、夸大收益或隐瞒免责条件,引发监管处罚。2…...

2025最权威的六大AI辅助写作神器解析与推荐

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 人工智能技术飞速发展的当下,AI辅助学术写作成了研究热点,借助AI撰写…...

博士论文不是“本科生Pro版”,好写作AI的“学术脚手架”让孤独的长征有迹可循

在多年的论文写作科普中,我最常被博士生问到的问题不是“怎么写”,而是“凭什么”。 凭什么我的研究是“原创”?凭什么我的论证经得起拷问?凭什么我的理论贡献能让答辩委员会点头? 这些问题的背后,藏着一…...

2026 年 UI/UX 设计师最常用的 AI 工具完整清单:从原型到代码交付

本文适合:希望用 AI 工具系统提升设计交付效率的 UI/UX 设计师、正在评估哪些 AI 能力是设计工作流必须具备的设计负责人,以及需要独立完成从原型设计到前端代码交付全流程的独立设计师和小型设计团队。 2026 年,UI/UX 设计师需要具备的 AI …...

SAE J1708/J1587协议详解:从协议栈到真实卡车诊断案例解析

SAE J1708/J1587协议深度解析:从数据帧到发动机诊断实战 重型商用车电子系统的神经脉络里,流淌着SAE J1708/J1587协议的数据血液。当一辆40吨的卡车在洲际公路上疾驰时,这套诞生于1980年代的通信标准仍在忠实地传递着发动机转速、燃油压力和故…...

解决Raspberry Pi上的jInput库问题

引言 在使用Java开发跨平台的应用程序时,处理不同操作系统下的库文件加载问题是一个常见的挑战。尤其是在Raspberry Pi(Pi3B+)上运行时,jInput库的加载问题可能会困扰不少开发者。本文将通过一个实例,详细介绍如何解决在Raspbian64系统上jInput库加载失败的问题。 问题描…...

Boss直聘爬虫数据采集:从手机热点切换IP到账号池管理的避坑指南

Boss直聘数据采集系统工程指南:从IP轮换到自动化容错设计 在招聘市场分析领域,Boss直聘作为头部平台积累了海量高价值数据。但想要稳定获取这些数据,传统单点突破的爬虫策略往往捉襟见肘。去年我们团队为某HR SaaS系统搭建采集架构时&#xf…...

终极Golang调试指南:从SSA中间码到DLV工具的完整调试艺术

终极Golang调试指南:从SSA中间码到DLV工具的完整调试艺术 【免费下载链接】golang-notes Go source code analysis(zh-cn) 项目地址: https://gitcode.com/gh_mirrors/go/golang-notes Golang-notes是一份全面的Go源代码分析笔记,涵盖了从语言特性…...