【数据结构】14 队列(带头结点的链式存储和顺序存储实现)

定义

队列是一个有序线性表,但是队列的插入、删除操作是分别在线性表的两个不同端点进行的。
设一个队列 Q = ( a 1 , a 2 , . . . , a n ) Q = (a_1, a_2,...,a_n) Q=(a1,a2,...,an),那么 a 1 a_1 a1被称为队头元素, a n a_n an为队尾元素。假如将元素A,B,C,D依次插入队列,第一个从队列中删除的元素为A,即先插入的将被先删除,故队列也称为先进先出表。

抽象数据类型
类型名称:队列
数据对象集:一个有0个或者多个元素的有穷线性表
操作集:对于一个长度为正整数MaxSize的队列 Q Q Q, 记队列中的任一元素 X X X,队列的基本操作集为:

  1. Queue CreateQueue(int MaxSize)
  2. bool IsFull(Queue Q)
  3. bool AddQ(Queue Q, ElementType X)
  4. bool Is Empty(Queue Q)
  5. ElementType DeleteQ(Queue Q)

队列的顺序存储实现

队列的最简单的表示方法是用数组。用数组存储队列有许多具体的方法。一般可以选择将队列头放数组下标小的位置,而将队列尾放在数组下标大的位置,并用两个变量Front和Rear分别指示队列的头和尾。一般把Front和Rear先初始化为-1。当有元素入队时,Rear向右移动一格,放入队尾元素;当有元素出队时,先将Front向右移动一格,再删除队首元素。
在这里插入图片描述
随着入队出队的进行会使整个队列整体向后移动这样就出现了如上图所示的现象,指针已经移到了最后,在再有元素入队时就会出现溢出,可是事实上此时队中并未真的满员,这种现象称为假溢出。

为了解决队尾溢出而实际上数组中仍有空余空间的问题,一般在队列的顺序存储结构中采用循环队列的方式,队尾指针和队首指针到达数组端点时能折回到数组开始处即相当于将数组头尾相接想象成环形,如图所示当插入和删除操作的作用单元达到数组的末端后用公式"Rear % 数组长度"取余运算就可以实现折返到起始单元。
在这里插入图片描述
队列初始化时,将Front和Rear都初始化为0,当插入一个元素时,Rear+1,删除一个元素时,Front加一。
当Front = Rear时,队列为空。
当队尾指针加1就会从后面赶上头指针,(Rear + 1)%数组长度 = Front
在这里插入图片描述

代码实现

顺序存储

数据结构

typedef int ElementType;
typedef int Position;
typedef struct QNode* PtrToQNode;
struct QNode {ElementType* Data;Position Front, Rear;int MaxSize;
};
typedef PtrToQNode Queue;

创建循环队列

Queue CreateQueue(int MaxSize) {Queue Q = (Queue)malloc(sizeof(struct QNode));Q->MaxSize = MaxSize;Q->Data = (ElementType*)malloc(sizeof(ElementType) * MaxSize);Q->Front = 0;Q->Rear = 0;return Q;
}

插入元素


bool IsFull(Queue Q) {if ((Q->Rear + 1) % Q->MaxSize == Q->Front) {return true;}else {return false;}
}bool AddQ(Queue Q, ElementType X) {if (IsFull(Q)) {printf("The Queue is full!\n");return false;}else {Q->Rear = (Q->Rear + 1) % Q->MaxSize;Q->Data[Q->Rear] = X;return true;}
}

删除元素

bool IsEmpty(Queue Q) {if (Q->Rear == Q->Front) {return true;}else {return false;}
}ElementType DeleteQ(Queue Q) {if (IsEmpty(Q)) {printf("The Queue is empty!\n");return -1;}else {Q->Front = (Q->Front + 1) % (Q->MaxSize);return Q->Data[(Q->Front)];}
}

完整代码

# include <stdio.h>
#include < stdlib.h>
#include <ctype.h>
#include <string.h>typedef int ElementType;
typedef int Position;
typedef struct QNode* PtrToQNode;
struct QNode {ElementType* Data;Position Front, Rear;int MaxSize;
};
typedef PtrToQNode Queue;Queue CreateQueue(int MaxSize) {Queue Q = (Queue)malloc(sizeof(struct QNode));Q->MaxSize = MaxSize;Q->Data = (ElementType*)malloc(sizeof(ElementType) * MaxSize);Q->Front = 0;Q->Rear = 0;return Q;
}bool IsFull(Queue Q) {if ((Q->Rear + 1) % Q->MaxSize == Q->Front) {return true;}else {return false;}
}bool AddQ(Queue Q, ElementType X) {if (IsFull(Q)) {printf("The Queue is full!\n");return false;}else {Q->Rear = (Q->Rear + 1) % Q->MaxSize;Q->Data[Q->Rear] = X;return true;}
}void printQ(Queue Q) {int f = Q->Front;int r = Q->Rear;while (f != r) {f = (f + 1) % (Q->MaxSize);printf("QNode: %d\n", Q->Data[f]);}
}bool IsEmpty(Queue Q) {if (Q->Rear == Q->Front) {return true;}else {return false;}
}ElementType DeleteQ(Queue Q) {if (IsEmpty(Q)) {printf("The Queue is empty!\n");return -1;}else {Q->Front = (Q->Front + 1) % (Q->MaxSize);return Q->Data[(Q->Front)];}
}int main() {Queue Q = CreateQueue(10);ElementType X;int N;scanf_s("%d", &N);while (N--) {scanf_s("%d", &X);if (AddQ(Q, X) == false) {printf("Add error!\n");}}printQ(Q);while (!IsEmpty(Q)) {ElementType out = DeleteQ(Q);printf("Out : %d\n", out);printf("\n");printQ(Q);}}

链式存储

队列的头必须指向的是队列的头结点,队尾指向链表的尾节点

数据结构

typedef int ElementType;
typedef struct Node* PtrToNode;
struct Node {ElementType Data;PtrToNode Next;
};typedef struct Node* Position;struct QNode {Position Rear, Front;int MaxSize;
};
typedef struct QNode * Queue;

队列的创建

Queue CreateQueue(int MaxSize) {Queue Q = (Queue)malloc(sizeof(struct QNode));Q->MaxSize = MaxSize;PtrToNode L = (PtrToNode)malloc(sizeof(struct Node));L->Next = NULL;Q->Front = L;Q->Rear = L;printf("finish!\n");return Q;}

加入元素


bool IsFull(Queue Q) {int cnt = 0;Position t = Q->Front;while (t != Q->Rear) {t = t->Next;cnt++;}printf("cnt : %d\n", cnt);if (cnt == Q->MaxSize) {return true;}else {return false;}
}bool AddQ(Queue Q, ElementType X) {if (IsFull(Q)) {printf("The Queue is full!\n");return false;}Position R = Q->Rear;while (R->Next != NULL) {R = R->Next;}PtrToNode t = (PtrToNode)malloc(sizeof(struct Node));t->Data = X;t->Next = R->Next;R->Next = t;Q->Rear = t;return true;}

删除元素


bool IsEmpty(Queue Q) {if (Q->Front->Next == NULL) {return true;}else {return false;}
}ElementType DeleteQ(Queue Q) {if(IsEmpty(Q)) {printf("The Queue is empty!\n");return -1;}else {ElementType t = Q->Front->Next->Data;Position te = Q->Front;Q->Front->Next = Q->Front->Next->Next;return t;}
}

完整代码

# include <stdio.h>
#include < stdlib.h>
#include <ctype.h>
#include <string.h>typedef int ElementType;
typedef struct Node* PtrToNode;
struct Node {ElementType Data;PtrToNode Next;
};typedef struct Node* Position;struct QNode {Position Rear, Front;int MaxSize;
};
typedef struct QNode * Queue;Queue CreateQueue(int MaxSize) {Queue Q = (Queue)malloc(sizeof(struct QNode));Q->MaxSize = MaxSize;PtrToNode L = (PtrToNode)malloc(sizeof(struct Node));L->Next = NULL;Q->Front = L;Q->Rear = L;printf("finish!\n");return Q;}bool IsFull(Queue Q) {int cnt = 0;Position t = Q->Front;while (t != Q->Rear) {t = t->Next;cnt++;}printf("cnt : %d\n", cnt);if (cnt == Q->MaxSize) {return true;}else {return false;}
}bool AddQ(Queue Q, ElementType X) {if (IsFull(Q)) {printf("The Queue is full!\n");return false;}Position R = Q->Rear;while (R->Next != NULL) {R = R->Next;}PtrToNode t = (PtrToNode)malloc(sizeof(struct Node));t->Data = X;t->Next = R->Next;R->Next = t;Q->Rear = t;return true;}void printq(Queue Q) {Position t = Q->Front;while (t != Q->Rear){t = t->Next;printf("QNode: %d\n", t->Data);}}bool IsEmpty(Queue Q) {if (Q->Front->Next == NULL) {return true;}else {return false;}
}ElementType DeleteQ(Queue Q) {if(IsEmpty(Q)) {printf("The Queue is empty!\n");return -1;}else {ElementType t = Q->Front->Next->Data;Position te = Q->Front;Q->Front->Next = Q->Front->Next->Next;return t;}
}int main() {Queue Q = CreateQueue(10);ElementType X;int N;scanf_s("%d", &N);while (N--) {scanf_s("%d", &X);if (AddQ(Q, X) == false) {printf("Add error!\n");}}printq(Q);while (!IsEmpty(Q)) {int out = DeleteQ(Q);printf("\n");printf("Out : %d\n", out);//printq(Q);}}

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

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

相关文章

手把手教你开发Python桌面应用-PyQt6图书管理系统-图书信息修改实现

锋哥原创的PyQt6图书管理系统视频教程&#xff1a; PyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~_哔哩哔哩_bilibiliPyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~共计24条视频&…

从互联网的公开信息中,找到属于你的赚钱思路

一、教程描述 人们在互联网上的每一次搜索、每一次关注、每一次点击、每一次点赞、每一次评论、每一次付费&#xff0c;都生成了大量的数据和信息&#xff0c;暴露着人们的真实想法、欲望、恐惧和需求。这些数据和信息&#xff0c;就是我们身边的一座“金矿”&#xff0c;而大…

1【算法】——最大子数组问题(maximum subarray)

一.问题描述 假如我们有一个数组&#xff0c;数组中的元素有正数和负数&#xff0c;如何在数组中找到一段连续的子数组&#xff0c;使得子数组各个元素之和最大。 二.问题分析 分治法求解&#xff1a; 初始状态&#xff1a; low0&#xff1b;highA.length-1&#xff1b;mid&am…

最新的 Ivanti SSRF 零日漏洞正在被大规模利用

Bleeping Computer 网站消息&#xff0c;安全研究员发现 Ivanti Connect Secure 和 Ivanti Policy Secure 服务器端请求伪造 (SSRF) 漏洞&#xff08;CVE-2024-21893 &#xff09;正在被多个威胁攻击者大规模利用。 2024 年 1 月 31 日&#xff0c;Ivanti 首次就网关 SAML 组件…

万维网的文档

目录 1 万维网的文档 动态万维网文档 CGI CGI 网关程序 活动万维网文档 用 Java 语言创建活动文档 1 万维网的文档 分为&#xff1a; 静态万维网文档。内容不会改变。简单。(html、xml、css) 动态万维网文档。文档的内容由应用程序动态创建。 活动万维网文档。由浏览器端…

SpringBoot3整合Knife4j

前置&#xff1a; 官网&#xff1a;快速开始 | Knife4j gitee&#xff1a;swagger-bootstrap-ui-demo: knife4j 以及swagger-bootstrap-ui 集成框架示例项目 - Gitee.com 1.依赖引入&#xff1a; ps&#xff1a;json处理需要引入相关包 <dependency><groupId>c…

基于语义解析的知识图谱问答系统

目录 前言1 背景介绍2 语义解析的核心技术2.1 自然语言处理&#xff08;NLP&#xff09;2.2 语义表示学习2.3 实体关系抽取 3 语义解析的基本步骤3.1 短语检测3.2 资源映射3.3 语义组合3.4 逻辑表达式生成 4 处理与知识图谱无关的问句4.1 Bridging技术4.2 确定谓词4.3 Paraphra…

【新书推荐】7.4节 寄存器间接和相对寻址方式

本节内容&#xff1a;当指令操作数为内存操作数&#xff0c;且内存操作数的地址使用指针寄存器表示时&#xff0c;称为寄存器间接寻址方式。 ■寄存器间接寻址方式&#xff1a;在地址表达式中&#xff0c;只能使用BX、SI、DI、BP四个指针寄存器用来寻址。 7.4.1 寄存器间接寻…

猫头虎分享已解决Bug || API限制超额(API Rate Limiting):RateLimitExceeded, APILimitReached

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

mysql入门到精通006-基础篇-多表查询

1、多表关系介绍 1.1 概念 项目开发中&#xff0c;在进行数据库表结构设计时&#xff0c;会根据业务需求和业务模块之间的关系&#xff0c;分析并设计表结构&#xff0c;由于业务之间相互关联&#xff0c;所以各个表结构之间也存在各种联系&#xff0c;基本上分为3种&#xf…

LeetCode.144. 二叉树的前序遍历

题目 144. 二叉树的前序遍历 分析 这道题目是比较基础的题目&#xff0c;我们首先要知道二叉树的前序遍历是什么&#xff1f; 就是【根 左 右】 的顺序&#xff0c;然后利用递归的思想&#xff0c;就可以得到这道题的答案&#xff0c;任何的递归都可以采用 栈 的结构来实现…

Microsoft Word 清除格式

Microsoft Word 清除格式 References 选择文本&#xff0c;用快捷键 Ctrl Shift N&#xff0c;可以快速清除格式。 选择文本&#xff0c;清除格式。 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

leetcode(矩阵)74. 搜索二维矩阵(C++详细解释)DAY7

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中…

Confluence CVE-2023-22527利用工具

介绍 Confluence CVE 2021&#xff0c;2022&#xff0c;2023 利用工具&#xff0c;支持命令执行&#xff0c;哥斯拉&#xff0c;冰蝎 内存马注入 支持 Confluence 版本&#xff1a;CVE-2021-26084&#xff0c;CVE-2022-26134&#xff0c;CVE_2023_22515&#xff0c;CVE-2023-2…

计算机网络——06分组延时、丢失和吞吐量

分组延时、丢失和吞吐量 分组丢失和延时是怎样发生的 在路由器缓冲区的分组队列 分组到达链路的速率超过了链路输出的能力分组等待排到队头、被传输 延时原因&#xff1a; 当当前链路有别的分组进行传输&#xff0c;分组没有到达队首&#xff0c;就会进行排队&#xff0c;从…

【MySQL进阶之路】生产案例:大量数据刷盘导致的数据库性能抖动问题优化

欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术的推送&#xff01; 在我后台回复 「资料」 可领取编程高频电子书&#xff01; 在我后台回复「面试」可领取硬核面试笔记&#xff01; 文章导读地址…

【Docker】Docker Container(容器)

文章目录 一、什么是容器&#xff1f;二、为什么需要容器&#xff1f;三、容器的生命周期容器OOM容器异常退出容器暂停 四、容器命令详解docker createdocker logsdocker attachdocker execdocker startdocker stopdocker restartdocker killdocker topdocker statsdocker cont…

Apache 神禹(shenyu)源码阅读(一)——Admin向Gateway的数据同步(Admin端)

源码版本&#xff1a;2.6.1 单机源码启动项目 启动教程&#xff1a;社区新人开发者启动及开发防踩坑指南 源码阅读 前言 开了个新坑&#xff0c;也是第一次阅读大型项目源码&#xff0c;写文章记录。 在写文章前&#xff0c;已经跑了 Divide 插件体验了一下&#xff08;体…

DataEase

一. DataEase (一). 说明 安装文档 DataEase 是开源的数据可视化分析工具&#xff0c;帮助用户快速分析数据并洞察业务趋势&#xff0c;从而实现业务的改进与优化。DataEase 支持丰富的数据源连接&#xff0c;能够通过拖拉拽方式快速制作图表&#xff0c;并可以方便的与他人分…

比特币突然大涨

作者&#xff1a;秦晋 2月9日&#xff0c;除夕夜&#xff0c;比特币突然大涨&#xff0c;最高涨至48219美元&#xff0c;涨幅超6%。据CNBC报道&#xff0c;本周比特币已经上涨10.76%&#xff0c;创下自12月8日以来的最佳的一周。本周ETH上涨8.46%&#xff0c;成为自1月12日以来…