用队列实现栈 用栈实现队列 设计循环队列

用队列实现栈 

思路

栈的特点:后进先出   

队列的特点:先进先出

 使用两个队列实现栈:

 

我们可以使用两个队列,一个队列为:空队列,一个队列为:非空队列

当我们要出队列时:

将 size - 1个数据移动到空队列中,再将最后一个数据出队列,如此往复就可以完成4 3 2 1的出队列顺序

代码(c语言): 

队列的各种功能:

typedef int QDataType;
// 链式结构:表示队列 
typedef struct QListNode
{struct QListNode* _next;QDataType _data;
}QNode;// 队列的结构 
typedef struct Queue
{QNode* _front;QNode* _rear;int size;
}Queue;
// 初始化队列 
void QueueInit(Queue* q) {assert(q);q->size = 0;q->_front = NULL;q->_rear = NULL;
}
// 队尾入队列 
void QueuePush(Queue* q, QDataType data) {assert(q);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("QueuePush()::malloc()");return;}newnode->_data = data;newnode->_next = NULL;//队列为NULLif (q->_front == NULL){q->_front = q->_rear = newnode;}else{q->_rear->_next = newnode;q->_rear = q->_rear->_next;}q->size++;
}
// 队头出队列 
void QueuePop(Queue* q) {assert(q);assert(q->size != 0);//单个节点if (q->_front == q->_rear){free(q->_front);q->_front = q->_rear = NULL;}//多个节点else{QNode* next = q->_front->_next;free(q->_front);q->_front = next;}q->size--;
}
// 获取队列头部元素 
QDataType QueueFront(Queue* q) {assert(q);assert(q->_front);//队头不能为NULLreturn q->_front->_data;
}
// 获取队列队尾元素 
QDataType QueueBack(Queue* q) {assert(q);assert(q->_rear);//队尾不能为NULLreturn q->_rear->_data;
}
// 获取队列中有效元素个数 
int QueueSize(Queue* q) {return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q) {assert(q);return q->size == 0;
}
// 销毁队列 
void QueueDestroy(Queue* q) {assert(q);QNode* cur = q->_front;while (cur){QNode* next = cur->_next;free(cur);cur = next;}q->_front = q->_rear = NULL;q->size = 0;}

具体实现:

//使用两个队列实现栈
typedef struct {Queue q1;Queue q2;} MyStack;//初始化栈
MyStack* myStackCreate() {//创建一个栈MyStack* newStk = (MyStack*)malloc(sizeof(MyStack));//初始化栈(即初始化两个队列)QueueInit(&(newStk->q1));QueueInit(&(newStk->q2));return newStk;
}//入栈
void myStackPush(MyStack* obj, int x) {//假设法找不为NULL的队列Queue* noempty = &obj->q1;if(QueueSize(noempty) == 0){noempty = &obj->q2;}//往不为NULL队列中插入QueuePush(noempty,x);
}//出栈
int myStackPop(MyStack* obj) {//假设法判断NULL队列,非NULL队列Queue* empty = &obj->q1;Queue* noempty = &obj->q2;if(QueueSize(noempty) == 0){noempty = &obj->q1;empty = &obj->q2;}//将size - 1个数据移动到NULL队列中while(QueueSize(noempty) > 1){QueuePush(empty,QueueFront(noempty));QueuePop(noempty);}//出栈int pop = QueueBack(noempty);QueuePop(noempty);return pop;}//获取栈顶元素
int myStackTop(MyStack* obj) {Queue* noempty = &obj->q1;if(QueueSize(noempty) == 0){noempty = &obj->q2;}//获取栈顶数据,也就是队尾的数据return QueueBack(noempty);}//判NULL
bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);}//销毁栈
void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);}

用栈实现队列

思路

使用两个栈实现队列

固定两个栈,1. 存数据栈(pushst) 2. 出数据栈(popst)

当我们要出数据时,把存数据栈(pushst)导入到 出数据栈(popst)中,在对栈顶取数据,如此往复就可以实现 4 3 2 1 的出栈顺序

代码(c语言):

栈的各种功能:

typedef int STDataType;typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;// 初始化和销毁
void STInit(ST* pst)
{assert(pst);pst->a = NULL;// top指向栈顶数据的下一个位置pst->top = 0;// top指向栈顶数据//pst->top = -1;pst->capacity = 0;
}void STDestroy(ST* pst)
{assert(pst);free(pst->a);pst->a = NULL;pst->top = pst->capacity = 0;
}// 入栈  出栈
void STPush(ST* pst, STDataType x)
{assert(pst);// 扩容if (pst->top == pst->capacity){int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}pst->a = tmp;pst->capacity = newcapacity;}pst->a[pst->top] = x;pst->top++;
}void STPop(ST* pst)
{assert(pst);assert(pst->top > 0);pst->top--;
}// 取栈顶数据
STDataType 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;
}
typedef struct {ST pushst;//用来存储数据ST popst;//用来导出数据} MyQueue;

具体实现

//用两个栈实现队列
MyQueue* myQueueCreate() {MyQueue* new = (MyQueue*)malloc(sizeof(MyQueue));STInit(&new->pushst);STInit(&new->popst);return new;
}//入队列
void myQueuePush(MyQueue* obj, int x) {STPush(&obj->pushst,x);//插入至数据栈(pushst)中}//查看队头元素
int myQueuePeek(MyQueue* obj) {//查看出数据栈(popst),中是否有数据,有则直接查看栈顶数据,没有就把存数据栈(pushst)导入到 出数据栈(popst)中if(STEmpty(&obj->popst)){//把pushst数据全部导入popstwhile(!STEmpty(&obj->pushst)){STPush(&obj->popst,STTop(&obj->pushst));STPop(&obj->pushst);}}//返回出数据栈(popst)栈顶数据return STTop(&obj->popst);}//出队列
int myQueuePop(MyQueue* obj) {//它会帮我们导数据到popst中,popst栈顶的数据就是我们要删除的数据int pop = myQueuePeek(obj);STPop(&obj->popst);return pop;
}//判空
bool myQueueEmpty(MyQueue* obj) {return STEmpty(&obj->pushst) && STEmpty(&obj->popst);//两个栈为NULL则队列为NULL}//销毁队列
void myQueueFree(MyQueue* obj) {STDestroy(&obj->pushst);STDestroy(&obj->popst);free(obj);
}

设计循环队列

        

 思路

利用数组来创建循环队列

代码:

typedef struct {int* a;int head;int rear;//指向最后一个数据的下一个空间int k;
} MyCircularQueue;//初始化循环队列
MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* new = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));//多开一个空间,用来解决数据为满与空的矛盾问题,当然也可以在结构体多加个size解决new->a = (int*)malloc(sizeof(int) * (k + 1));new->head = 0;new->rear = 0;//尾数据的下一个位置new->k = k;return new;
}//插入队列
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//判断循环队列满没有,满则不能继续插入if((obj->rear + 1) % (obj->k + 1) == obj->head)//当尾数据指针 + 1 = 头指针时,队列满return false;obj->a[obj->rear] = value;obj->rear++;obj->rear %= obj->k + 1;//循环return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {//判断队列是否为空,为空则不能继续删除if(obj->head == obj->rear)//当尾指针 = 头指针时,队列为空return false;obj->head++;obj->head %= obj->k + 1; //循环return true;
}//返回队列头数据
int myCircularQueueFront(MyCircularQueue* obj) {if(obj->head == obj->rear)return -1;return obj->a[obj->head];
}//返回队列尾数据,即找尾指针指向的上一个地方
int myCircularQueueRear(MyCircularQueue* obj) {if(obj->head == obj->rear)return -1;return obj->a[(obj->k + obj->rear) % (obj->k + 1)];//往前绕k-1去找rear之前的一个数据}//判空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {//空return obj->head == obj->rear;
}//判满
bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->rear + 1) % (obj->k + 1) == obj->head;}//销毁队列
void myCircularQueueFree(MyCircularQueue* obj) {free(obj->a);free(obj);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/333334.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多态

多态的概念 通俗来说,就是多种形态,具体点就是完成某个行为,当不同的对象去完成时会产生出不同的状态 多态的定义及实现 多态构成的条件 1、必须通过基类的指针或者引用调用虚函数 2、子类必须对基类的虚函数进行重写 虚函数 被关键字vi…

内网横向移动小补充 --->PTK

大家别急,我的基于资源的约束性委派攻击还在写,这个东西一时半会讲不清楚,所以我在这里先来补充一点横向移动以前没说好的东西!!! 在更啦,别催啦~~~~ 还记得我之前在内网渗透里面讲过这个PTK&a…

2024.5.22 关于 SpringCloud —— Nacos 配置管理

目录 Nacos 配置统一管理 Nacos 配置热部署 Nacos 多环境配置共享 配置优先级 Nacos 配置统一管理 实例理解 我们想要利用 Nacos 在 user-service 的 application.yml 配置文件中新增配置项此处我们将新增配置日期格式为 yyyy-MM-dd HH:mm:ss下图为新增 Nacos 配置统一管理…

基于STM32实现智能园艺系统

目录 引言环境准备智能园艺系统基础代码示例:实现智能园艺系统 土壤湿度传感器数据读取水泵控制温湿度传感器数据读取显示系统用户输入和设置应用场景:智能农业与家庭园艺问题解决方案与优化收尾与总结 1. 引言 本教程将详细介绍如何在STM32嵌入式系统…

基于Zynq 7000 SoC的迁移设计

基于Zynq 7000 SoC的迁移设计 Vivado IDE工具使用IP集成器进行嵌入式开发。各种IP Vivado IDE IP目录中提供,以适应复杂的设计。您也可以添加 自定义IP到IP目录。 您可以将基于Zynq 7000平台处理器的设计迁移到Vivado design Suite中 使用以下步骤。 1.生成系统基础…

【搜索方法推荐】高效信息检索方法和实用网站推荐

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…

亚马逊云主管马特·加尔曼面临压力,致力于在人工智能领域赶超竞争对手

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

四川景源畅信:抖音小店新手如何做?

随着短视频平台的兴起,抖音小店成为了许多创业者的新选择。但是,对于新手来说,如何在抖音上开设并经营好自己的小店呢?本文将围绕这一问题展开讨论。 一、明确目标和定位作为抖音小店的新手,首先要明确自己的经营目标和定位。是想…

【CTF Web】CTFShow web4 Writeup(SQL注入+PHP+字符型注入)

web4 1 管理员阿呆又失败了&#xff0c;这次一定要堵住漏洞 解法 注意到&#xff1a; <!-- flag in id 1000 -->拦截很多种字符&#xff0c;连 select 也不给用了。 if(preg_match("/or|\-|\\\|\/|\\*|\<|\>|\!|x|hex|\(|\)|\|select/i",$id)){die(&q…

Pycharm最新安装教程(最新更新时间2024年5月27日)

ps&#xff1a;本教程Pycharm安装&#xff0c;最新更新时间&#xff1a;2024年5月27日&#xff0c;公众号持续更新关注公众号防失联哦 Pycharm 再次更新了一个小版本。又回到老话题&#xff0c;2023.3.2这个版本是否还能安装&#xff0c;笔者也亲测了一下。还是沿用本站之前的…

刷题之从前序遍历与中序遍历序列构造二叉树(leetcode)

从前序遍历与中序遍历序列构造二叉树 前序遍历&#xff1a;中左右 中序遍历&#xff1a;左中右 前序遍历的第一个数必定为根节点&#xff0c;再到中序遍历中找到该数&#xff0c;数的左边是左子树&#xff0c;右边是右子树&#xff0c;进行递归即可。 #include<vector>…

零基础PHP入门(一)选择IDE和配置环境

配置环境 官网下载安装包&#xff0c;windows https://windows.php.net/download#php-8.3 我是下载的最新版&#xff0c;也可以切换其他版本 https://windows.php.net/downloads/releases/archives/ 下载好压缩文件后&#xff0c;双击解压到一个目录 D:\soft\php 复制ph…

技术贴 | Query 物理计划构建指南

在往期博客《执行器 - Query 执行详解》中&#xff0c;我们介绍到到一条 Query 的 SQL 语句需要经过&#xff1a;词法分析 —— 生成 AST 语法树 —— 生成物理计划。本期博客我们接续上篇讲解一条 Query 语句物理计划的具体结构&#xff0c;以及如何构建物理计划。 物理计划是…

无人机技术:倾转旋翼飞行器的关键技术详解

一、总体设计 倾转旋翼飞行器作为一种独特的垂直起降与水平巡航的航空器&#xff0c;其总体设计是关键技术之一。总体设计涵盖了飞行器的整体布局、重量分配、气动性能、机械结构设计等多个方面。在总体设计中&#xff0c;需要充分考虑飞行器的垂直起降、悬停、过渡飞行和水平…

Android14之Binder调试(二百一十一)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

气泡水位计的安装方法详解(二)

气泡水位计的安装方法详解&#xff08;二&#xff09; 产品简介 气泡式水位计ZL-BWL-013是一款适用于水文、水利信息化建设领域的新一代水位测量类设备&#xff0c;产品执行GB/T 11828.2-2022标准。ZL-BWL-013气泡水位计&#xff0c;具有安装方便、易于操作&#xff0c;高精度…

【leetcode2028. 找出缺失的观测数据(自己写出来了)】

给你一个长度为 m 的整数数组 rolls &#xff0c;其中 rolls[i] 是第 i 次观测的值。同时给你两个整数 mean 和 n 。返回一个长度为 n 的数组&#xff0c;包含所有缺失的观测数据&#xff0c;且满足这 n m 次投掷的 平均值 是 mean 。如果存在多组符合要求的答案&#xff0c;只…

Springboot阶段项目---《书城项目》

一 项目介绍 本项目采用集成开发平台IntelliJ IDEA开发了在线作业成绩统计系统的设计与实现&#xff0c;实现了图书商城系统的综合功能和图形界面的显示&#xff0c;可以根据每个用户登录系统后&#xff0c;动态展示书城首页图书&#xff0c;实现了分类还有分页查询&#xff0c…

【加密与解密(第四版)】第十六章笔记

第十六章 脱壳技术 16.1 基础知识 壳的加载过程&#xff1a;保存入口参数、获取壳本身需要使用的API地址、解密原程序各个区块的数据、IAT的初始化、重定位项的处理、HOOK API、跳转到程序原入口点 手动脱壳步骤&#xff1a;查找真正的入口点、抓取内存映像文件、重建PE文件&…

图论(二)-图的建立

引言&#xff1a; 建图&#xff0c;将图放进内存的方法 常用的建图方式&#xff1a;邻接矩阵&#xff0c;邻接链表&#xff0c;链式前向星 一、邻接矩阵 通过一个二维数组即可将图建立&#xff0c;邻接矩阵&#xff0c;考虑节点集合 &#xff0c;用一个二维数组定义邻接矩…