队列(8.6)
目录
2.队列
2.1队列的概念及结构
2.2队列的实现
2.2.1初始化队列
2.2.2队尾入队列
2.2.3队头出队列
2.2.4获取队列头部元素
2.2.5 销毁队列
3.栈和队列面试题
225. 用队列实现栈 - 力扣(LeetCode)
232. 用栈实现队列 - 力扣(LeetCode)
编辑
622. 设计循环队列 - 力扣(LeetCode)
编辑
2.队列
2.1队列的概念及结构
将队列运用于抽号机能够计算出排队需要的等待的时间,需要等待前面的人数等信息,也能实现叫号(取队头)操作,能够实现绝对的公平,不存在插队现象。
2.2队列的实现
2.2.1初始化队列
// 初始化队列
void QueueInit(Que* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
} 2.2.2队尾入队列
// 队尾入队列
void QueuePush(Que* pq, QDataType x)
{assert(pq);//开辟新节点QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc");exit(-1);}//初始化新节点newnode->data = x;newnode->next = NULL;//判断队列是否为空if (pq->tail == NULL){pq->head = pq->tail = newnode;}//不为空尾插else{pq->tail->next = newnode;pq->tail = newnode;}
} 2.2.3队头出队列

// 队头出队列
void QueuePop(Que* pq)
{assert(pq);//列表不能为空assert(!QueueEmpty(pq));//如果列表只剩一个成员if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}//正常头删else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
} 2.2.4获取队列头部元素
// 获取队列头部元素
QDataType QueueFront(Que* pq)
{assert(pq);//检查列表不为空assert(!QueueEmpty(pq));return pq->head->data;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Que* pq)
{assert(pq);//列表为空返回1,不为空返回0return pq->head == NULL;
} 2.2.5 销毁队列
// 销毁队列
void QueueDestroy(Que* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
} 2.2.6 探空
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Que* pq)
{assert(pq);//列表为空返回1,不为空返回0return pq->head == NULL;
} 3.栈和队列面试题
225. 用队列实现栈 - 力扣(LeetCode)
分析:创建两个队列入队列:入不为空的队列出队列:出不为空的前n-1个元素,插入到空队列,删除剩余元素
typedef int QDataType;typedef struct QueueNode
{QDataType data;struct QueueNode* next;}QNode;
typedef struct Que
{QNode* head;QNode* tail;int size;
}Que;// 初始化队列
void QueueInit(Que* pq);
// 队尾入队列
void QueuePush(Que* pq, QDataType x);
// 队头出队列
void QueuePop(Que* pq);
// 获取队列头部元素
QDataType QueueFront(Que* pq);
// 获取队列队尾元素
QDataType QueueBack(Que* pq);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Que* pq);
// 销毁队列
void QueueDestroy(Que* pq);
//队列节点数
int QueueSize(Que* pq);// 初始化队列
void QueueInit(Que* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}// 队尾入队列
void QueuePush(Que* pq, QDataType x)
{assert(pq);//开辟新节点QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc");exit(-1);}//初始化新节点newnode->data = x;newnode->next = NULL;//判断队列是否为空if (pq->tail == NULL){pq->head = pq->tail = newnode;pq->size++;}//不为空尾插else{pq->tail->next = newnode;pq->tail = newnode;pq->size++;}
}// 队头出队列
void QueuePop(Que* pq)
{assert(pq);//列表不能为空assert(!QueueEmpty(pq));//如果列表只剩一个成员if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}//正常头删else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}// 获取队列头部元素
QDataType QueueFront(Que* pq)
{assert(pq);//检查列表不为空assert(!QueueEmpty(pq));return pq->head->data;
}// 获取队尾元素
QDataType QueueBack(Que* pq)
{assert(pq);//检查列表不为空assert(!QueueEmpty(pq));return pq->tail->data;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Que* pq)
{assert(pq);//列表为空返回1,不为空返回0return pq->head == NULL;
}
// 销毁队列
void QueueDestroy(Que* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}
//队列节点数
int QueueSize(Que* pq)
{assert(pq);return pq->size;
}//定义列表的结构体
typedef struct {Que q1;Que q2;
} MyStack;
//列表初始化
MyStack* myStackCreate() {//不能直接初始化,临时变量,出函数销毁,需要开辟空间MyStack* pst=(MyStack*)malloc(sizeof(MyStack));//参数为队列的指针QueueInit(&pst->q1);QueueInit(&pst->q2);return pst;
}void myStackPush(MyStack* obj, int x) {//谁不为空push到谁if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}
}
//出栈
int myStackPop(MyStack* obj) {//随便假设一个为空队列,一个为非空Que* empty=&obj->q1;Que* nonempty=&obj->q2;//如果假设错误,就交换if(!QueueEmpty(&obj->q1)){nonempty=&obj->q1;empty=&obj->q2;}//将非空栈出到剩尾元素为止while(QueueSize(nonempty)>1){//非空栈入到空栈QueuePush(empty,QueueFront(nonempty));//入一个出一个QueuePop(nonempty);}//保存尾元素int top=QueueFront(nonempty);//出掉尾元素QueuePop(nonempty);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)
{//结构体指针下创建了两个列表,需要先释放列表QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);
}/*** 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);
*/ 232. 用栈实现队列 - 力扣(LeetCode)
栈的特性是先后进先出,队列的特性是先进先出;若想用栈实现先进先出,就需要另创建一个栈,将原栈中的数据倒过去就能够轻松实现。


原栈中的数据倒过去之后,此时插入数据,直接插入到原栈中,用原栈专门用来接收数据,如果再出栈,用一个栈专门出栈,当专门出栈的栈出空之后,再从原栈倒数据过来;而不用每次出栈都把数据倒出去又倒回来,很麻烦。


typedef int STDataType;
//支持动态增长的栈
typedef struct Stack
{STDataType* a;int top;//栈顶int capacity;//容量
}ST;// 初始化栈
void STInit(ST* ps);
// 入栈
void STPush(ST* ps, STDataType x);
// 出栈
void STPop(ST* ps);
// 获取栈顶元素
STDataType STTop(ST* ps);
// 获取栈中有效元素个数
int STSize(ST* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool STEmpty(ST* ps);
// 销毁栈
void STDestroy(ST* ps);void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}void STPush(ST* ps, STDataType x)
{assert(ps);// 11:40if (ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;
}void STPop(ST* ps)
{assert(ps);// assert(ps->top > 0);--ps->top;
}STDataType STTop(ST* ps)
{assert(ps);// assert(ps->top > 0);return ps->a[ps->top - 1];
}int STSize(ST* ps)
{assert(ps);return ps->top;
}bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}//定义两个栈类型
typedef struct {ST pushst;ST popst;
} MyQueue;//开辟并初始化结构体变量
MyQueue* myQueueCreate() {MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));STInit(&obj->pushst);STInit(&obj->popst);return obj;
}void myQueuePush(MyQueue* obj, int x) {//始终往push栈上面pushSTPush(&obj->pushst,x);
}
//出队列
int myQueuePop(MyQueue* obj) {int front=myQueuePeek(obj);//与peek唯一不同之处就是取得队头后删掉STPop(&obj->popst);return front;
}
//取队头数据
int myQueuePeek(MyQueue* obj) {if(STEmpty(&obj->popst)){//pop为空,从push倒数据while(!STEmpty(&obj->pushst)){//pop入一个STPush(&obj->popst,STTop(&obj->pushst));//push出一个STPop(&obj->pushst);}}//不为空,直出return STTop(&obj->popst);
}bool myQueueEmpty(MyQueue* obj) {//两个栈都为空才为空return STEmpty(&obj->pushst)&&STEmpty(&obj->popst);
}void myQueueFree(MyQueue* obj) {STDestroy(&obj->pushst);STDestroy(&obj->popst);free(obj);
}/*** 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);
*/ 622. 设计循环队列 - 力扣(LeetCode)
我们用数组来实现,给数组多开一个 rear 空间(不存数据)用来解决探空和探满的问题

front 为列表头节点的下标,rear 为为尾节点的下一个节点的下标;front 和rear 初始值为0,push 一次 rear ++一次,由于列表是定长的,因此当push 了k个数据时,列表就放满了,不能再入数据。放满的标志为此时列表的实际长度(包括 rear节点)对理论长度 k+1 取余的结果等于 front 。

pop操作,我们直接让 front ++,遵循先进先出的原则。

push 操作,push 一次,rear 向后移动一次,直到 rear 的下一个为 front ,则代表放满,标志依然为(rear+1)%(k+1)=front ,当rear<k,就等于 rear +1= front。

此时再 pop 到 front 处于数组末尾,继续 pop,front 就转到数组开头,当 rear 和 front 重合且为空时,数组就为空。
//定义队列
typedef struct {//数组int *a;//头int front;//尾int rear;//数组长度(不包含rear)int k;
} MyCircularQueue;
//初始化队列
MyCircularQueue* myCircularQueueCreate(int k) {//为队列开空间MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));//为数组开空间,多开一个rear用于探空(满)obj->a=(int*)malloc(sizeof(int)*(k+1));obj->front=obj->rear=0;obj->k=k;return obj;
}
//探空(非0为空,0为非空)
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {//front和rear相等就是空return obj->front==obj->rear;}
//探满(非0为满,0为未满)
bool myCircularQueueIsFull(MyCircularQueue* obj) {//rear的下一个为front为满;rear在队尾,front在对头为满。return (obj->rear+1)%(obj->k+1)==obj->front;}
//插入
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//先探满if(myCircularQueueIsFull(obj)){return false;}//正常情况下往rear位置放数据,放完后移obj->a[obj->rear]=value;obj->rear++;//如果rear走到队尾之后(++之后等于k),那么++之后应该挪到队头(归0,因此取模)//取模操作在走过队尾之前无效obj->rear%=(obj->k+1);return true;
}
//删除
bool myCircularQueueDeQueue(MyCircularQueue* obj) {//先探空if(myCircularQueueIsEmpty(obj)){return false;}//正常情况下front后移obj->front++;//如果front走到队尾之后(++之后等于k),那么++之后应该挪到队头(归0,因此取模)obj->front%=(obj->k+1);return true;
}
//取头
int myCircularQueueFront(MyCircularQueue* obj) {//探空if(myCircularQueueIsEmpty(obj)){return -1;}else{return obj->a[obj->front];}
}
//取尾(取rear的上一个节点)
int myCircularQueueRear(MyCircularQueue* obj) {//探空if(myCircularQueueIsEmpty(obj)){return -1;}else{//+k并对k+1取余,当rear在队头,上一个节点就在队尾//不在队头时取余结果刚好为上一个节点return obj->a[(obj->rear+obj->k)%(obj->k+1)];}}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->a);free(obj);}/*** Your MyCircularQueue struct will be instantiated and called as such:* MyCircularQueue* obj = myCircularQueueCreate(k);* bool param_1 = myCircularQueueEnQueue(obj, value);* bool param_2 = myCircularQueueDeQueue(obj);* int param_3 = myCircularQueueFront(obj);* int param_4 = myCircularQueueRear(obj);* bool param_5 = myCircularQueueIsEmpty(obj);* bool param_6 = myCircularQueueIsFull(obj);* myCircularQueueFree(obj);
*/
相关文章:
队列(8.6)
目录 2.队列 2.1队列的概念及结构 2.2队列的实现 2.2.1初始化队列 2.2.2队尾入队列 2.2.3队头出队列 2.2.4获取队列头部元素 2.2.5 销毁队列 3.栈和队列面试题 225. 用队列实现栈 - 力扣(LeetCode) 232. 用栈实现队列 - 力扣(LeetC…...
计算机网络 第四章网络层
文章目录 1 网络层的功能2 数据交换方式:电路交换3 数据交换方式:报文交换4 数据交换方式:分组交换5 数据交换方式:数据报方式6 数据交换方式:虚电路方式及各种方式对比7 路由算法及路由协议8 IP数据报的概念和格式9 I…...
操作系统运行机制
文章目录 操作系统运行机制特权指令VS非特权指令内核态VS用户态中断和异常内中断(异常)外中断中断机制基本原理中断处理过程 系统调用系统调用和库函数的区别为什系统调用时必须的?什么功能需要用到系统调用系统调用的过程小结 操作系统内核 操作系统运行机制 特权…...
mathtype7.4破解永久激活码
MathType(数学公式编辑器)是由Design Science公司研发的一款专业的数学公式编辑工具。MathType功能非常强大,尤其适用于专门研究数学领域的人群使用。使用MathType让你在输入数学公式的时候能够更加的得心应手,各种复杂的运算符号也不在话下。 MathType最…...
66 内网安全-域横向批量atschtasksimpacket
目录 演示案例:横向渗透明文传递at&schtasks 案例2-横向渗透明文HASH传递atexec-impacket案例3-横向渗透明文HASH传递批量利用-综合案例5-探针主机域控架构服务操作演示 传递攻击是建立在明文和hash值的一个获取基础上的攻击,也是在内网里面常见协议的攻击&…...
PCI9054入门1:硬件引脚定义、时序、FPGA端驱动源码
文章目录 1:PCI9054的FPGA侧(local侧引脚定义)2:PCI9054的C模式下的读写时序3:FPGA代码部分具体代码: 1:PCI9054的FPGA侧(local侧引脚定义) 而PCI9054的本地总线端的主要…...
多媒体应用设计师 第17章 多媒体应用场景的技术应用和实现示例
口诀 思维导图 2020...
react151618刷新几次的问题
结论: 16 hooks版本 默认render1次 同步中,无论多少种类还是次数,都render 1次。 异步中,无论多少种类还是次数,1个种类执行1次,多次的话,用n*2。 18 hooks版本 默认render2次, 同步…...
【Spring】IOC容器与Bean的常用属性配置
文章目录 1.前言2.IOC容器2.1 BeanFactory 容器2.2 ApplicationContext 容器 3.Bean的常用属性配置4. 总结 1.前言 在之前的文章-IOC的快速入门中讲过Bean这个概念. 本来就来介绍容器与Bean的常用属性配置 在Spring框架中,Bean指的是被Spring加载生成出来的对象。 …...
2023年下半年 系统集成项目管理工程师 真题考点(一二三四批次)(10月28、29)(网友回忆版)
文章目录 第一批部分考点整体管理采购管理风险管理二:EAC 第二批部分考点如下: 第三批部分考点如下: 第一批 部分考点 1、案例考了关键路径和工期,风险管理、采购、风险、招投标,整体管理。 2、计算题有关键路径和挣…...
读韩都衣舍,谈权力转移的激励制度
这是一个很久之前的商业案例。 在大公司,管理过于复杂,成了现在公司管理的大问题。大公司的流程长,市场的突击速度慢,以及员工的积极性差,成为大公司的一个潜在的弊病。而最近,从韩都衣舍的创始人赵迎光的…...
私有云:【10】VCenter安装win10
私有云:【10】VCenter安装win10 1、ESXI挂载win10镜像2、VCenter安装win102.1、创建虚拟机2.2、启动虚拟机 此WIN10用来作为以后的远程桌面 1、ESXI挂载win10镜像 2、VCenter安装win10 2.1、创建虚拟机 创建虚拟机 设置名称下一步 选择计算机资源 选择NFS存储 设置…...
[Java/力扣100]判断两棵二叉树是否相同
我希望通过这道题,能进一步了解递归思想和“树是递归定义的”这句话 分析 我们的目的是写一个方法来检验两棵树是否相同 什么叫“两棵树相同”?——相同的位置存在相同的结点 有三种情况:1、两棵树一颗为空一颗不为空——不相同ÿ…...
BEC商务英语主题 定价策略|柯桥学商务英语口语
Factors in Pricing Decisions 影响价格制定的因素 A firm cannot determine a product’s price without considering several factors that affect price. 在制定产品价格时,公司如果不考虑影响价格的各种因素是无法制定的。 Managers must take into account t…...
第七章 ObjectScript 一般系统限制
文章目录 第七章 ObjectScript 一般系统限制 字符串长度限制下标限制Global的最大长度 第七章 ObjectScript 一般系统限制 字符串长度限制 字符串的长度有限制:3,641,144 个字符。 重要的是要认识到字符串不仅仅是从输入/输出设备读取的结果。它们可以显示在其他上…...
【Python百练——第1练】使用Python求100以内的所有偶数
作者:Insist-- 个人主页:insist--个人主页 作者简介:梦想从未散场,传奇永不落幕,持续更新优质网络知识、Python知识、Linux知识以及各种小技巧,愿你我共同在CSDN进步 欢迎点赞👍收藏Ὄ…...
springboot心理咨询管理系统
springboot心理咨询管理系统,java心理咨询管理系统,心理咨询管理系统 运行环境: JAVA版本:JDK1.8 IDE类型:IDEA、Eclipse都可运行 数据库类型:MySql(8.x版本都可) 硬件环境…...
Java-API简析_java.net.URL类(基于 Latest JDK)(浅析源码)
【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/134024288 出自【进步*于辰的博客】 因为我发现目前,我对Java-API的学习意识比较薄弱…...
C语言浮点型在内存中的存储
目录 前言: 引言: 浮点数存储规则 举个栗子: TIP: 单精度浮点数存储的模型(float) 双精度浮点数存储的模型(double) IEEE对 M 的特殊规定 IEEE对 E 的特殊规定 小试牛刀 先…...
elementPlus | el-tabs 标签管理路由页面
<script setup> import { useRouter } from vue-router const router useRouter()const tabClick (tab)>{const idx tab.indexif(idx 0){router.push(/)}... } </script> <template><!-- 撑开 stretch"true" --><el-tabs type&quo…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...
阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...
Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...


