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

队列算法精讲:从栈与队列互实现到循环队列(待补充)

目录

  • 前言
  • 一、队列算法题
    • 1.1 用队列实现栈
    • 1.2 用栈实现队列
    • 1.3 设计循环队列
  • 结语

在这里插入图片描述

在这里插入图片描述

🎬 云泽Q:个人主页

🔥 专栏传送入口: 《C语言》《数据结构》《C++》《Linux》

⛺️遇见安然遇见你,不负代码不负卿~

前言

大家好啊,我是云泽Q,一名热爱计算机技术的在校大学生。近几年人工智能技术飞速发展,为了帮助大家更好地抓住这波浪潮,在开始正文之前,我想先为大家推荐一个非常优质的人工智能学习网站)。它提供了从基础到前沿的系列课程和实战项目,非常适合想要系统入门和提升AI技术的朋友,相信能对你的学习之路有所帮助。

一、队列算法题

1.1 用队列实现栈

用队列实现栈
在这里插入图片描述
在这里插入图片描述

队列先进先出
在这里插入图片描述

  1. 入栈:往不为空的队列中插入数据

在这里插入图片描述

  1. 出栈:把不为空队列中前size-1个数据挪到另一个队列,再将最后一个数据出队列

在这里插入图片描述
此时q2不为空
在这里插入图片描述
在这里插入图片描述
此时q1不为空
在这里插入图片描述
在这里插入图片描述
最后直接将最后一个数据出队列
在这里插入图片描述

  1. 取栈顶:取栈顶不能按之前出栈的老套路,如果将前size-1个数据挪到另一个队列,取栈顶不同于出栈,是不出数据的,此时q1有1个数据,q2有3个数据,此时就会导致两个队列均不为空,完成第一次取栈顶后,就无法完成出栈了

在这里插入图片描述
所以正确的取栈顶方式就是前size-1不挪数据,找不为空的队列,返回队尾数据
在这里插入图片描述
在这里插入图片描述
创建一个栈的返回值是一个指向上面结构体的指针,所以要向操作系统申请一个MyStack大小的空间,空间申请下来了,指针才能指向MyStack,pst指向操作系统申请的一个栈大小的空间

完整源码

typedef int QDataType;
//定义节点结构
typedef struct QueueNode
{QDataType data;struct QueueNode* next;
}QueueNode;
//定义队列结构
typedef struct Queue
{QueueNode* phead;//队头QueueNode* ptail;//队尾//int size;        //队列中有效元素个数
}Queue;//初始化
void QueueInit(Queue* pq)
{assert(pq);pq->phead = pq->ptail = NULL;//pq->size = 0;
}//入队--队尾
void QueuePush(Queue* pq, QDataType x)
{assert(pq);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = NULL;if (pq->phead == NULL){pq->phead = pq->ptail = newnode;//pq->size++;}else {pq->ptail->next = newnode;pq->ptail = pq->ptail->next;//pq->size++;}
}//判断队列是否为空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL;
}//出队--对头
void QueuePop(Queue* pq)
{assert(!QueueEmpty(pq));if (pq->phead == pq->ptail){free(pq->phead);pq->phead = pq->ptail = NULL;//pq->size--;}else {QueueNode* next = pq->phead->next;free(pq->phead);pq->phead = next;//pq->size--;}
}//取对头数据
QDataType QueueFront(Queue* pq)
{assert(!QueueEmpty(pq));return pq->phead->data;
}//取队尾数据
QDataType QueueBack(Queue* pq)
{assert(!QueueEmpty(pq));return pq->ptail->data;
}//队列中有效元素个数
int QueueSize(Queue* pq)
{assert(pq);QueueNode* pcur = pq->phead;int size = 0;while (pcur){++size;pcur = pcur->next;}return size;//return pq->size;
}//销毁队列
void QueueDestory(Queue* pq)
{assert(pq);QueueNode* pcur = pq->phead;while (pcur){QueueNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = pq->ptail = NULL;
}//----------------------以上是队列的结构和常用的方法-------------------------typedef struct {Queue q1;Queue q2;
} MyStack;//创建一个栈
MyStack* myStackCreate() {MyStack* pst=(MyStack*)malloc(sizeof(MyStack));//初始化队列QueueInit(&pst->q1);QueueInit(&pst->q2);return pst;
}//入栈
void myStackPush(MyStack* obj, int x) {//往不为空的队列中插入数据if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}
}//出栈
int myStackPop(MyStack* obj) {//找不为空队列//假设q1为空,q2非空Queue* emp=&obj->q1;Queue* noneEmp=&obj->q2;if(QueueEmpty(&obj->q2)){emp=&obj->q2;noneEmp=&obj->q1;}//将不为空队列前size-1个数据挪到空队列中while(QueueSize(noneEmp)>1){//取队头,入另一个队列,这里也可以用一个变量来接收队头,然后再入队列QueuePush(emp,QueueFront(noneEmp));//出队头QueuePop(noneEmp);}//不为空队列最后一个数据出队int top=QueueFront(noneEmp);QueuePop(noneEmp);return top;
}//取栈顶
int myStackTop(MyStack* obj) {//找不为空队列,返回不为空队列的队尾数据if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}
}//判断栈是否为空
bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}//栈的销毁
void myStackFree(MyStack* obj) {QueueDestory(&obj->q1);QueueDestory(&obj->q2);free(obj);obj=NULL;
}/*** Your MyStack struct will be instantiated and called as such:* MyStack* obj = myStackCreate();* myStackPush(obj, x);* int param_2 = myStackPop(obj);* int param_3 = myStackTop(obj);* bool param_4 = myStackEmpty(obj);* myStackFree(obj);
*/

1.2 用栈实现队列

用栈实现队列
在这里插入图片描述
在这里插入图片描述
这里思路就要转变了,一个栈用来入数据,一个栈用来出数据

  1. 入队列:往pushST插入数据

在这里插入图片描述
若popST中没有数据,则将pushST中的数据全部导入popST中,然后出popST中的数据
在这里插入图片描述
在这里插入图片描述
还有一种情况,先在pushST中插入1,2
在这里插入图片描述
此时popST中为空,没有数据可出,将pushST中的数据导过去
在这里插入图片描述
之后将1出数据,此时又在pushST中入队列3,4
在这里插入图片描述
此时popST不为空,就直接出数据,此时popST中为空了,再进行导数据
在这里插入图片描述
导完了之后再出数据

  1. 也就是出队列这里有一个前提,popST不为空直接出,否则将pushST中的数据先导过去再出数据

接下来就是取队头
在这里插入图片描述
popST为空,先导数据
在这里插入图片描述
此时1是队头,便取队头,注意是取不是出,然后出数据
在这里插入图片描述
之后就正常取队头,出对头就可以了,因为popST不为空,栈顶就是队头数据,不用导数据

  1. 逻辑和队列一样,但是不出数据,popST不为空直接取队头,否则将pushST中的数据先导过去再取队头

返回值MyQueue* 是指向MyQueue这个结构的指针,所以像操作系统申请一个MyQueue大小的空间
在这里插入图片描述

完整源码

//定义栈的结构 - Stack是栈的名称
typedef int STDataType;
typedef struct Stack {STDataType* arr;//存储数据的数组int top;//top指向栈顶的位置,刚好就是栈中有效数据个数int capacity;//栈的空间大小
}ST;//初始化
void STInit(ST* ps)
{ps->arr = NULL;ps->top = ps->capacity = 0;
}//销毁
void STDesTroy(ST* ps)
{//arr不能为空,为空的话都没有向操作系统中申请内存,就没有必要销毁了if (ps->arr)free(ps->arr);ps->arr = NULL;ps->capacity = ps->top = 0;
}//入栈---栈顶
void STPush(ST* ps, STDataType x)
{assert(ps);//判断空间是否足够if (ps->top == ps->capacity){//增容int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//如果capacity为0,就给4,realloc第二个参数的单位为字节,这里要申请4个整型空间,而不是4个字节STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}//空间足够ps->arr[ps->top++] = x;
}//判断栈是否为空
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}//出栈---栈顶
void STPop(ST* ps)
{assert(!STEmpty(ps));ps->top--;
}//取栈顶元素
STDataType STTop(ST* ps)
{assert(!STEmpty(ps));return ps->arr[ps->top - 1];
}//获取栈中有效元素个数
int STSize(ST* ps)
{assert(ps);return ps->top;
}
//------------------------------以上是栈结构的定义和常见的方法---------------------------typedef struct {ST pushST;ST popST;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* pq=(MyQueue*)malloc(sizeof(MyQueue));STInit(&pq->pushST);STInit(&pq->popST);return pq;
}//入队列
void myQueuePush(MyQueue* obj, int x) {//往pushST插入数据STPush(&obj->pushST,x);
}//出队列
int myQueuePop(MyQueue* obj) {//popST为空---将pushST(不为空)导入popSTif(STEmpty(&obj->popST)){while(!STEmpty(&obj->pushST)){//取栈顶,入popST,出栈STPush(&obj->popST,STTop(&obj->pushST));STPop(&obj->pushST);}}//popST不为空直接出数据int top=STTop(&obj->popST);STPop(&obj->popST);return top;
}//取队头
int myQueuePeek(MyQueue* obj) {//popST为空---将pushST(不为空)导入popSTif(STEmpty(&obj->popST)){while(!STEmpty(&obj->pushST)){//取栈顶,入popST,出栈STPush(&obj->popST,STTop(&obj->pushST));STPop(&obj->pushST);}}//popST不为空直接取数据int top=STTop(&obj->popST);return top;
}//两个栈实现一个队列,两个栈都为空,队列才可以为空
bool myQueueEmpty(MyQueue* obj) {return STEmpty(&obj->popST) && STEmpty(&obj->pushST);
}void myQueueFree(MyQueue* obj) {STDesTroy(&obj->popST);STDesTroy(&obj->pushST);free(obj);obj=NULL;
}/*** Your MyQueue struct will be instantiated and called as such:* MyQueue* obj = myQueueCreate();* myQueuePush(obj, x);* int param_2 = myQueuePop(obj);* int param_3 = myQueuePeek(obj);* bool param_4 = myQueueEmpty(obj);* myQueueFree(obj);
*/

1.3 设计循环队列


结语

在这里插入图片描述

http://www.dtcms.com/a/439191.html

相关文章:

  • 蝴蝶优化算法:原理、改进与应用
  • 你会怎么做外国的网站建一个购物网站多少钱
  • 数据驱动下的集成学习实战:从算法选型到业务落地的完整方法论
  • dw旅游网站模板下载物流网站如何设计
  • 建网站能挣钱吗WordPress老文章提示
  • 类中特殊成员(Num018)
  • 网站策划书市场分析商场设计案例分析
  • 比利时网站后缀做漫画封面的网站
  • [创业之路-666]:第四次工业革命(智能革命)未来将创造大量的财富,普通人通过哪些方式参与这些财富的创造与分享?
  • 力扣2653. 滑动子数组的美丽值
  • 网站开发的常见编程语言有哪些成都广告公司招聘信息
  • 给网站做引流多少钱网站sem怎么做
  • 辽宁省水利建设市场信用信息平台网站营销推广策划
  • 欢迎进入河南国安建设集团有限公司网站十大不收费看盘软件排名下载
  • 淘宝上面建设网站安全么夜猫直播视频下载
  • 宝应网站设计17做网站 一件代发
  • DBCA静默创建Oracle CDB与PDB:两种实战方法详解
  • ARM内核
  • 佛山网站建设哪个wordpress主题汉化版
  • 乐山网站制作设计公司网页设计规范图标设计
  • Kubernetes中配置NGINX仅支持TLSv1.3全攻略
  • 国外直播做游戏视频网站有哪些开个网站卖机器怎么做
  • c 网站开发架构多用户商城app
  • 【面板数据】华政ESG评级年度中位数年度均值(2009-2024年)
  • ORB_SLAM2原理及代码解析:ORBmatcher::SearchForInitialization() 函数
  • 国家城乡和建设厅特殊工种网站网站建设需求多少钱大概
  • 系统架构设计师教程第二版重要的图
  • 网站开发代码无中文ppt制作网站推荐
  • 因果推断想突破传统局限?深度学习 × 结构经济模型,异质性研究的创新契机在这
  • 郑州网站推广报价做淘宝优惠券网站要多少钱