发布时间:2026/7/18 4:42:48
数据结构:队列和栈的相互实现 文章目录前言一、队列实现栈1.2 代码的实现1.2.1结构体的构建1.2.2 初始化1.2.3 模型入栈1.2.4 模拟出栈并返回栈顶元素1.2.5 获取栈顶元素1.2.6 判空1.2.7 释放二 栈实现队列2.1 思路分析2.2 代码实现2.2.1 结构体的构建2.2.2 初始化2.2.3 将元素 x 推到队列的末尾(模拟入队)2.2.4 返回队列开头的元素2.2.5 从队列的开头移除并返回元素(模拟出队)2.2.6 判空2.2.7 销毁前言虽然在实践中没有什么意义但是可以帮助我们熟悉和了解栈和队列一、队列实现栈思路如下图所示队列的规则是先进先出而栈的规则是后进先出如图中q1我们入队1、2、3、4按照栈我们出栈的是4因此我们将q1中的红色框中的数据导给q2然后剩下44直接出队就达到了效果。当我们出完4后当我们想入数据是给q1还是q2呢q2假设我们入给q1如下图所示然后我们需要6出队该怎么出呢是不是想将5导入到q2再出6那如果我再出5你是不是要让q2的1、2、3、4导给q1然后出5。如果再进行push呢又给q2吗这样会一直导来导去逻辑会混乱。那栈顶的数据我们就不知道是在q1还是在q2。因此我们需要向非空的队列中去push数据。1.2 代码的实现首先需要了解队列的实现#includestdio.h#includestdlib.h#includeassert.h#includestdbool.htypedefintQDataTpye;typedefstructQueueNode{QDataTpye val;structQueueNode*next;}QueueNode;typedefstructQueue{QueueNode*ptail;QueueNode*phead;intsize;}Queue;//初始化voidQueueInit(Queue*pq);//队尾插入voidQueuePush(Queue*pq,QDataTpye x);//队头删除voidQueuePop(Queue*pq);//取队头队尾的数据QDataTpyeQueueFront(Queue*pq);QDataTpyeQueueBack(Queue*pq);//个数intQueueSize(Queue*pq);//判空boolQueueEmpty(Queue*pq);//销毁voidQueueDestory(Queue*pq);voidQueueInit(Queue*pq){assert(pq);pq-pheadpq-ptailNULL;pq-size0;}voidQueuePush(Queue*pq,QDataTpye x){assert(pq);QueueNode*newnode(QueueNode*)malloc(sizeof(QueueNode));if(newnodeNULL){perror(QueuePush::malloc);return;}newnode-nextNULL;newnode-valx;//空的if(pq-pheadNULL){pq-pheadpq-ptailnewnode;}else//尾插{pq-ptail-nextnewnode;pq-ptailnewnode;}pq-size;}intQueueSize(Queue*pq){assert(pq);returnpq-size;}voidQueuePop(Queue*pq){assert(pq);assert(pq-size!0);//一个节点if(pq-phead-nextNULL){free(pq-phead);pq-pheadpq-ptailNULL;}else{QueueNode*nextpq-phead-next;free(pq-phead);pq-pheadnext;}pq-size--;}QDataTpyeQueueFront(Queue*pq){assert(pq);assert(pq-phead);returnpq-phead-val;}QDataTpyeQueueBack(Queue*pq){assert(pq);assert(pq-ptail);returnpq-ptail-val;}boolQueueEmpty(Queue*pq){assert(pq);returnpq-size0;}voidQueueDestory(Queue*pq){assert(pq);QueueNode*curNULL;curpq-phead;while(cur){QueueNode*temcur-next;free(cur);curtem;}pq-pheadpq-ptailNULL;pq-size0;在实现队列的基础上再来用两个队列实现栈1.2.1结构体的构建首先我们需要封装一个结构体来管理这两个队列typedefstructMyStack{Queue q1;Queue q2;}MyStack;1.2.2 初始化对结构体进行初始化MyStack*MyStackCreat(){MyStack*pst(MyStack*)malloc(sizeof(MyStack));if(pstNULL){perror(MyStackCreat::malloc);exit(1);}QueueInit((pst-q1));QueueInit((pst-q2));returnpst;}1.2.3 模型入栈谁不为空就入给谁都为空随便入voidmyStackPush(MyStack*obj,QDataTpye x){if(!QueueEmpty((obj-q1))){QueuePush((obj-q1),x);}else{QueuePush((obj-q2),x);}}1.2.4 模拟出栈并返回栈顶元素intmyStackPop(MyStack*obj){//假设法MyStack*Empty(obj-q1);MyStack*nonEmpty(obj-q2);if((obj-q2)NULL){nonEmpty(obj-q1);Empty(obj-q2);}//不为空前size-1导走删除最后一个就是栈顶数据while(QueueSize(nonEmpty)1){QueuePush(Empty,QueueFront(nonEmpty));QueuePop(nonEmpty);}inttopQueueFront(nonEmpty);QueuePop(nonEmpty);returntop;}1.2.5 获取栈顶元素找到不为空的队列返回队尾元素就是栈顶元素intmyStackTop(MyStack*obj){if(!QueueEmpty((obj-q1))){returnQueueBack(((obj-q1)));}else{returnQueueBack(((obj-q2)));}}1.2.6 判空也就是判断两个队列是否为空boolmyStckEmpty(MyStack*obj){returnQueueEmpty((obj-q2))QueueEmpty((obj-q1));}1.2.7 释放直接释放obj没有当我们直接释放掉obj时除了释放掉了obj后面的都没有释放掉会造成内存泄漏voidmyStackFree(MyStack*obj){QueueDestory((obj-q1));QueueDestory((obj-q2));free(obj);}这里obj置不置空都行它是一级指针只起到传值的作用改变不了实参。二 栈实现队列2.1 思路分析首先我们需要明白栈是后进先出而队列是先进先出。和上面队列实现栈一样我们将一个不为空的栈导到另外一个栈去然后出栈是不是就达到效果了。此时第一个栈就变成空如果我们再想入栈数据该怎么办呢是向非空的栈入数据的话我们就需要保持之前的顺序需要将第二个栈的数据导到第一个栈然后入栈数据然后再将这个数据导入到第二个栈中出栈这也是可以的但是很麻烦。因此我们只需要将一个栈作为入栈另一个栈出栈就好了比如之前导好后的数据我们需要再入栈就向最开始导的栈中入然后等另外一个栈所有的数据完成出栈后再将数据导入进去。2.2 代码实现首先我们需要在实现栈的基础上完成。typedefintSTDataType;typedefstruct{STDataType*arr;//指向栈数组空间的指针inttop;//栈顶位置intcapacity;//容量}Stack;//栈的初始化voidStackInit(Stack*s);//栈的销毁voidStackDestory(Stack*s);//核心逻辑//x元素入栈voidStackPush(Stack*s,STDataType x);//将栈顶元素出栈并返回栈顶元素STDataTypeStackPop(Stack*s);//获取栈顶元素并返回STDataTypeStackTop(Stack*s);//获取栈中有效元素个数intStackSize(Stack*s);//检测栈是否为空如果是空返回真否则返回假boolStackEmpty(Stack*s);voidStackInit(Stack*s){assert(s);s-arr(STDataType*)malloc(4*sizeof(STDataType));//开辟四个元素的空间if(s-arrNULL){perror(StackInit::malloc);return;}// 初始化时top 0表⽰top指向的是栈顶元素的下⼀个位置// 初始化时top -1表⽰top指向的是栈顶元素s-top0;s-capacity0;}voidStackPush(Stack*s,STDataType x){assert(s);//空间扩容if(s-capacitys-top){intnewcapacitys-capacity0?4:2*s-capacity;STDataType*tem(STDataType*)realloc(s-arr,sizeof(STDataType)*newcapacity);if(temNULL){perror(tem::realloc);exit(1);}s-arrtem;s-capacitynewcapacity;}//入栈s-arr[s-top]x;}STDataTypeStackPop(Stack*s){assert(s);//判断是否为空如为空就没有出栈的必要if(!StackEmpty(s))returns-arr[--s-top];}STDataTypeStackTop(Stack*s){assert(s);if(!StackEmpty(s))returns-arr[s-top-1];//top0,指向的是栈顶下一个位置}intStackSize(Stack*s){assert(s);returns-top;}boolStackEmpty(Stack*s){assert(s);returns-top0;}voidStackDestory(Stack*s){assert(s);if(s-arr){free(s-arr);s-arrNULL;s-top0;s-capacity0;}}2.2.1 结构体的构建在栈的结构上构建两个栈一个栈作为入栈一个栈作为出栈typedefstructSTQ{Stack s1;//栈1入栈Stack s2;//栈2出栈}MyQueue;2.2.2 初始化MyQueue*myQueueCreate(){MyQueue*obj(MyQueue*)malloc(sizeof(MyQueue));if(objNULL){perror(myQueueCreate::malloc);exit(1);}StackInit((obj-s1));StackInit((obj-s2));returnobj;}2.2.3 将元素 x 推到队列的末尾(模拟入队)voidmyQueuePush(MyQueue*obj,intx){assert(obj);StackPush((obj-s1),x);}2.2.4 返回队列开头的元素我们先确定s2是否为空为空我们需要将s1的数据导入s2中然后去s2的栈顶元素即可intmyQueuePeek(MyQueue*obj){assert(obj);if(StackEmpty((obj-s2))){//导数据while(!StackEmpty((obj-s1))){inttopStackTop((obj-s1));StackPush((obj-s2),top);StackPop((obj-s1));}}returnStackTop((obj-s2));}2.2.5 从队列的开头移除并返回元素(模拟出队)这个和上面的2.2.4差不多都需要导入数据但是导入数据后只需要pop就可以了。intmyQueuePop(MyQueue*obj){assert(obj);inttopmyQueuePeek((obj-s2));StackPop((obj-s2));returntop;}2.2.6 判空boolmyQueueEmpty(MyQueue*obj){assert(obj);returnStackEmpty((obj-s1))StackEmpty((obj-s1));}2.2.7 销毁voidmyQueueFree(MyQueue*obj){StackDestory(obj-s1);StackDestory(obj-s2);free(obj);}

相关新闻

2026/7/18 4:42:48

DPWM技术解析:高效电力电子转换的核心

1. DPWM技术背景与核心价值在电力电子领域,PWM(脉宽调制)技术堪称现代功率变换器的"心脏"。而DPWM(Discontinuous Pulse Width Modulation,不连续脉宽调制)作为PWM家族中的重要分支,其…

2026/7/18 4:42:48

Java线程与CPU调度原理及性能优化实践

1. Java线程与CPU调度的核心关系 现代计算机系统中,CPU作为计算核心资源,其调度机制直接影响着Java多线程程序的执行效率。理解这两者的交互原理,是编写高性能并发程序的基础。我们先从最底层的硬件特性说起: CPU物理核心与逻辑线…

2026/7/18 4:37:47

射频功放(PA)核心参数解析与效率优化实践

1. 射频功放(PA)基础概念与核心价值射频功率放大器(Power Amplifier,简称PA)是无线通信系统中不可或缺的关键部件,它位于发射链路的末端,负责将调制后的射频信号放大到足够的功率电平&#xff0…

2026/7/18 5:52:54

Linux PREEMPT_RT 补丁:从软实时到硬实时的内核改造

前置知识:无需深厚内核功底,了解基础Linux系统编译、进程调度概念即可,零基础可跟随实操完成硬实时内核改造。为解决Linux实时性短板,Linux社区推出PREEMPT_RT 实时补丁集,也是目前工业界唯一通用、稳定、开源的Linux硬…

2026/7/18 5:52:54

Java: 集合

Java 集合类有哪些 Java 中的集合类主要由 Collection 和 Map 这两个接口派生而出,其中 Collection 接口又派生出三个子接口,分别是 Set、List、Queue。所有的 Java 集合类,都是 Set、List、Queue、Map 这四个接口的实现类。 Collection 接口…

2026/7/18 5:52:54

微服务架构下Spring Gateway+Sa-Token+Nacos认证鉴权实践

1. 微服务架构下的认证与鉴权挑战在分布式系统架构中,认证(Authentication)和鉴权(Authorization)是两个核心安全机制。认证解决"你是谁"的问题,而鉴权解决"你能做什么"的问题。传统单体应用通常采用Session或简单Token机制&#xf…

2026/7/18 5:52:54

C++游戏开发实战:从零构建高性能游戏引擎核心架构

1. 项目概述:为什么选择C进行游戏开发?如果你问一个干了十几年游戏引擎开发的老兵,为什么很多3A大作的“心脏”都是用C写的,而不是Java、C#或者Python,我通常会用一个比喻来回答:盖摩天大楼和搭乐高积木&am…

2026/7/18 5:52:54

AI Agent框架对比:Coze、Dify与LangChain技术解析

1. AI Agent 框架的崛起背景与核心价值2025年,全球AI Agent市场规模突破千亿美元,开发者面临的核心痛点从"如何调用大模型API"转变为"如何构建可持续演进的智能体系统"。在这个背景下,各类AI Agent框架应运而生&#xff…

2026/7/18 5:47:54

参数访问undefined类JSCrash问题分析

本原创文章帖发布在华为开发者联盟社区,欢迎开发者前往访问评论交流,更多与该内容相关讨论,请点击原帖查看: 参数访问undefined类JSCrash问题分析-华为开发者话题 | 华为开发者联盟 作为一名鸿蒙开发者,你一定遇到过这…

2026/7/17 5:59:06

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾在网易云音乐下载了心爱的歌曲&#…

2026/7/17 1:21:45

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境随着新能源汽车行业的快速发展,充电通信协议的标准化和测试验证变得尤为重要。GB/T 27930-2023作为中国智能充电协议的最新版本,对充电机与电动汽车之间的通信提出了更严格…

2026/7/17 7:39:19

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡 【免费下载链接】rtl8852be Realtek Linux WLAN Driver for RTL8852BE 项目地址: https://gitcode.com/gh_mirrors/rt/rtl8852be 还在为Linux系统无法识别RTL8852BE Wi-Fi 6网卡而烦恼吗?&#x1f…

2026/7/18 0:00:24

某智驾大牛创业

作者:钟声编辑:Mark出品:红色星际头图:智能驾驶图片据悉,国内某头部智驾公司端到端模型技术大牛Z投身创业,并且已经拿到融资。Z不仅是该头部公司内部最年轻的对标阿里P10级别技术负责⼈,更是业内…

2026/7/17 14:59:44

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…