【数据结构】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,一经查实,立即删除!

相关文章

金融科技力

金融科技 区块链二级目录三级目录 区块链 区块链安全&#xff1a;保密性、完整性、可用性 最重要的点&#xff1a;保密性零知识证明&#xff1a; 1、完整性&#xff08;真的假不了&#xff09; 2、可靠性&#xff08;假的真不了&#xff09; 3、零知识性&#xff08;知道真的&…

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

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

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

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

项目中的一些疑难杂记

疑难杂记 1. 关于正则表达式对象的匹配状态问题发现查找原因解决方法done 喜大普奔 1. 关于正则表达式对象的匹配状态 问题发现 因页面中多个函数使用到同一个正则表达式&#xff0c;想着定义个变量 export 出去然后在对应的函数中引用&#xff0c;一切正常中… 直到有一天&a…

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

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

CGAL::2D Arrangements-2

2.3.2 遍历Arrangement Halfedge Arrangement的一条Halfedge是和一个 X_monotone_curve_2对象绑定&#xff0c;这个curve可以通过e->curve()获取。 e->source()得到源点&#xff0c;e->target()得到目标点&#xff0c;e->twin()得到半边的对边&#xff0c; 第个半…

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

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

Java设计模式——策略

前言 策略模式是平时Java开发中常用的一种&#xff0c;虽然已有很多讲解设计模式的文章&#xff0c;但是这里还是写篇文章来从自己理解的角度讲解一下。 使用场景 我们不妨进行场景假设&#xff0c;要对我们的软件进行授权管理&#xff1a;在启动我们的软件之前先要校验是否…

万维网的文档

目录 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…

作业 2.12

封装strlen #include <stdio.h> #include <string.h> int main(int argc, const char *argv[]) { char arr[30]; gets(arr); char *paarr; int i0; int sum0; for(i0;arr[i]!\0;i) { sum; } printf("%d",s…

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

目录 前言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…

MongoDB聚合:$unwind

使用$unwind可以对输入文档数组字段进行结构&#xff0c;为每个数组元素输出一个文档&#xff0c;并且每个输出文档都是输入文档数组字段的值。相当于将内嵌的数组文档提升到了顶层。 语法 可以通过字段路径或文档操作符来展开数组字段。 通过字段操作符展开 可以将数组字段…

如何用 docker 部署程序?

如何用 docker 部署程序&#xff1f;这个问题有点笼统。 如果是MySQL、Redis这些&#xff0c;只需要拉取镜像&#xff0c;然后设置必要的配置&#xff0c;最终创建并运行实例即可。 如果你的应用是一个Java应用程序&#xff0c;使用Docker来部署它会涉及到Java特有的一些考虑…

c# Config 配置文件帮助类

public class ConfigHelper { #region 获取指定目录 AppSettings 配置文件值 /// <summary> /// 获取指定目录 AppSettings 配置文件值 /// </summary> /// <param name"key"></param> /// <…

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

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

片上网络NoC(1)——导论

一、多核时代的出现 自从20世纪90年代末引入多核芯片研究以来&#xff0c;片上网络已经成为一个重要且不断发展的研究领域。随着计算核心数量的不断增加&#xff0c;多核处理器被广泛应用在高端服务器、智能手机&#xff0c;甚至物联网&#xff08;Internet of Things,IoT)网关…