【数据结构】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.hqwc.cn/news/466435.html

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

相关文章

视觉开发板—K210自学笔记(五)

本期我们来遵循其他单片机的学习路线开始去用板子上的按键控制点亮LED。那么第一步还是先知道K210里面的硬件电路是怎么连接的&#xff0c;需要查看第二节的文档&#xff0c;看看开发板原理图到底是按键是跟哪个IO连在一起。然后再建立输入按键和GPIO的映射就可以开始变成了。 …

Vue核心基础5:数据监测、收集表单数据、过滤器

1 数据监测 【代码】 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>总结</title><scrip…

协议-TCP协议-基础概念04-可能发生丢包的位置-linux配置项梳理(TCP连接的建立和断开、收发包过程)

可能发生丢包的位置-linux配置项梳理&#xff08;TCP连接的建立和断开、收发包过程&#xff09;-SYN Flood攻击和防御原理 参考来源&#xff1a; 极客时间-Linux性能优化实战 极客时间-Linux内核技术实战课 到底是哪里发生了丢包呢&#xff1f; Linux 的网络收发流程 从图中…

OpenCV-36 多边形逼近与凸包

目录 一、多边形的逼近 二、凸包 一、多边形的逼近 findContours后的轮廓信息countours可能过于复杂不平滑&#xff0c;可以用approxPolyDP函数对该多边形曲线做适当近似&#xff0c;这就是轮廓的多边形逼近。 apporxPolyDP就是以多边形去逼近轮廓&#xff0c;采用的是Doug…

MySQL篇----第二十一篇

系列文章目录 文章目录 系列文章目录前言一、什么是乐观锁二、什么是悲观锁三、什么是时间戳四、什么是行级锁前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 一、…

【记录】电容的作用,调试Arduino及ESP8266

最近调试Arduino结合ESP8266进行WIFI传输和云端控制&#xff0c;准备用Arduino的3.3V输出直接作为ESP8266的电源&#xff0c;不想竟掉坑里了。 Arduino的3.3V输出接上ESP8266后&#xff0c;Arduino的程序就跑飞了。ESP8266刚上电还是相当生猛的&#xff0c;要吃掉一百多毫安的…

C++ Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统(2)折线图显示

对上一篇的工作C学习笔记 | 基于Qt框架开发实时成绩显示排序系统1-CSDN博客继续优化&#xff0c;增加一个显示运动员每组成绩的折线图。 1&#xff09;在Qt Creator的项目文件&#xff08;.pro文件&#xff09;中添加对Qt Charts模块的支持&#xff1a; QT charts 2&#xf…

回归预测模型:MATLAB岭回归和Lasso回归

1. 岭回归和Lasso回归的基本原理 1.1 岭回归&#xff1a; 岭回归&#xff08;Ridge Regression&#xff09; 是一种用于共线性数据分析的技术。共线性指的是自变量之间存在高度相关关系。岭回归通过在损失函数中添加一个L2正则项&#xff08; λ ∑ j 1 n β j 2 \lambda \s…

基于JAVA的软件学院思政案例库系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统管理员2.2 普通教师 三、系统展示四、核心代码4.1 查询思政案例4.2 审核思政案例4.3 查询思政课程4.4 思政案例点赞4.5 新增思政案例评语 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的软件学…

【Linux】基础命令 第二篇

目录 echo 输出重定向:(本质都是写入) 输入重定向cat more 指令 && less指令 head && tail && 管道初步使用 grep&#xff1a;行文本过滤工具&#xff08;文本按行搜索&#xff09; date&#xff1a;获取时间 date 命令用于 显示 或 设置系统的…

MATLAB Coder从入门到放弃

一、MATLAB Coder入门 1 MATLAB Coder是什么 从 MATLAB 代码生成 C 和 C 代码 MATLAB Coder™ 可从 MATLAB 代码生成适用于各种硬件平台&#xff08;从桌面计算机系统到嵌入式硬件&#xff09;的 C 和 C 代码。它支持大多数 MATLAB 语言和广泛的工具箱。您可以将生成的代码作…

4核8g服务器能支持多少人访问?2024新版测评

腾讯云轻量4核8G12M轻量应用服务器支持多少人同时在线&#xff1f;通用型-4核8G-180G-2000G&#xff0c;2000GB月流量&#xff0c;系统盘为180GB SSD盘&#xff0c;12M公网带宽&#xff0c;下载速度峰值为1536KB/s&#xff0c;即1.5M/秒&#xff0c;假设网站内页平均大小为60KB…