数据结构:队列和栈的相互实现

发布时间:2026/11/7 15:41:31

数据结构:队列和栈的相互实现 文章目录前言一、队列实现栈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/11/3 23:12:39

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

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

2026/11/6 11:10:47

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

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

2026/11/5 1:24:29

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

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

2026/11/7 15:39:52

曹县电工证在哪里考保姆级教程:电工证没到手,工作机会就没了

曹县电工证在哪里考保姆级教程:电工证没到手,工作机会就没了 你缺一张电工证,别人就多一份机会。在曹县,找电工相关的工作,电工证几乎是 硬性门槛 ,没有它,连面试资格都没有。尤其是现在企业招聘越来越规范,特种作业证成了“门槛证”,没有它,…

2026/11/7 15:39:52

曹县电工证在哪里考值不值得考

曹县电工证在哪里考值不值得考 之前考的证在外省能不能转过来?这是很多电工朋友心头的疑问。特别是在曹县,有些人在外地打工多年,考了电工证,回来之后却发现手续繁琐,甚至不知从何下手。 值不值得考…

2026/11/7 15:39:52

周先华高压电工证怎么报名 实操考试心里没底怕挂科?这3步教你搞定

周先华高压电工证怎么报名 实操考试心里没底怕挂科?这3步教你搞定 实操考试心里没底怕挂科?你不是一个人。特别是像我们平顶山市从事市政公用工程的朋友,高压电工证不仅是从业门槛,更是日常操作的“安全锁”。很多人在报名时对流程不清楚,对考试内容不…

2026/11/7 15:39:52

建筑特种工和技术工报名怕被坑?真实经历告诉你怎么避坑

建筑特种工和技术工报名怕被坑?真实经历告诉你怎么避坑 不知道去哪报名怕被中介坑,是很多初次报考建筑特种工和技术工的新人最真实的困扰。我自己当初也是在朋友介绍下,稀里糊涂地交了钱,结果证书还没拿到,钱就打水漂了。今天我就从一个过来人的角度,把…

2026/11/7 15:39:52

电工证能在异地年检吗 30天拿证攻略全解析

电工证能在异地年检吗 30天拿证攻略全解析 急需特种作业证才能上岗找工作,电工证作为高需求证书之一,不仅关系到能否入职,还直接决定了薪资水平和发展空间。不少朋友问: 电工证能在异地年检吗 ?更有人担心 多久拿证…

2026/11/7 15:34:51

证书过期了不知道怎么复审延期?硬件施工电工证上岗必备全流程详解

证书过期了不知道怎么复审延期?硬件施工电工证上岗必备全流程详解 证书过期了不知道怎么复审延期?你不是一个人,很多郑州市政公用工程从业者都遇到过这个问题。别急,下面一步步告诉你怎么搞定硬件施工电工证的复审和延期,确保你随时“上岗必备”,不掉链…

2026/11/7 14:54:47

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/7 14:50:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/7 0:03:08

郑州报考避坑指南:电工证和钳工证怎么选?实操考试心里没底怕挂科

郑州报考避坑指南:电工证和钳工证怎么选?实操考试心里没底怕挂科 实操考试心里没底怕挂科?你不是一个人。特别是在郑州这样的城市,很多施工企业负责人和一线作业人员在报考电工证和钳工证时都面临着同样的困惑。到底该考哪个证?哪个更适合自己?哪个证书…

2026/11/7 0:03:08

广西电工证办理流程全解析:外省证怎么转?在哪考最靠谱?

广西电工证办理流程全解析:外省证怎么转?在哪考最靠谱? 之前考的证在外省能不能转过来?这个问题我遇到太多了,今天就拿广西电工证办理流程来具体说说,别再走弯路了。广西电工证的报考、复审、继续教育这些环节,如果你不了解,真的会吃大亏,尤其对于从…

2026/11/7 0:03:08

电气电工证都有哪些保姆级教程

电气电工证都有哪些保姆级教程 你是不是正愁不知道去哪报名,怕被中介坑?别急,这篇保姆级教程专为河南初次报考人员准备,帮你搞清楚 电气电工证都有哪些 ,以及如何避开那些坑。 电气电工证都有哪些?别被五花八门的证书搞懵了…

2026/11/7 14:54:47

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/7 14:50:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑