环形队列出队的元素怎么输出出来_队列的知识讲解与基本实现(数据结构)

8c10ba9cef69aab1a5cd7e0d328bcb9c.png

引言

中午在食堂打饭,真是一个令人头疼的事情,去食堂的路上也总是步伐匆匆,为什么啊,这还用说,迟一点去,你就会知道什么叫做人山人海了,在食堂排队的时候,相比较学生来说,打饭阿姨毕竟是少数,在每个窗口都有人的时候,不免我们就得等待,直到前面的一个学生打完饭离开,后面排队的人才可以继续向前走,直到轮到自己,别提多费劲了,但是秩序和规则却是我们每个人都应该遵守的,也只能抱怨自己来的迟了

这种 “先进先出” 的例子就是我们所讲的基本数据结构之一 ”队列“

例子补充:用电脑的时候,有时候机器会处于疑似死机的状态, 鼠标点什么似乎都没有用,双击任何快捷方式都不动,就当你失去耐心,打算reset的时候,突然它就像酒醒了一样,把你刚才点击的所有操作全部按照顺序执行了一遍,这其实是因为操作系统中的多个程序隐需要通过一个通道输出,而按照先后次序排队等待造成的 ——《大话数据结构》

队列的基本定义

定义:队列是一种只允许在一段进行删除操作,在另一端进行插入操作的线性表

允许插入的一段称作队尾 (rear),允许删除的的一端称为队头 (front)

队列的数据元素又叫做队列元素,在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队 ,也正是因为队列只允许在一段插入,另一端删除,所以这也就是我们前面例子中体现出来的先进先出 (FIFO-first in first out) 的概念

ad381da3f168776242cdf9e9839cfd7b.png
补充:除此之外,还有的队列叫做双端队列,也就是可以在表的两边进行插入和删除操作的线性表
双端队列分类:
  1. 输出受限的双端队列:删除操作限制在表的一段进行,而插入操作允许早表的两端进行
  2. 插入操作限制在表的一段进行,而删除操作允许在表的两端进行

队列的抽象数据类型

 #ifndef _QUEUE_H_#define _QUEUE_H_#include <exception>using namespace std;​// 用于检查范围的有效性class outOfRange:public exception {     public:    const char* what()const throw() {   return "ERROR! OUT OF RANGE.n";} };  ​// 用于检查长度的有效性class badSize:public exception {            public:    const char* what()const throw() {return "ERROR! BAD SIZE.n";}  }; ​template <class T>class Queue {public://判队空 virtual bool empty() const = 0;//清空队列 virtual void clear() = 0;//求队列长度 virtual int size() const = 0;//入队 virtual void enQueue(const T &x) = 0;//出队 virtual T deQueue() = 0;//读队头元素 virtual T getHead() const = 0;//虚析构函数 virtual ~Queue(){} };#endif 

循环队列

队列作为一个特殊的线性表,自然也有着顺序以及链式存储两种方式,我们先来看看它的顺序存储方式——循环队列

在队列的顺序存储中,我们除了创建一个具有一定空间的数组空间外,还需要两个指针,分别指向队列的前端和微端,下面的代码中,我们选择将队头指针指向头元素的前一个位置,队尾指针指向队尾元素(当然这不是唯一的方式,还可以将头指针指向头元素,队尾指针指向队尾元素的后一个位置,原理是基本一致的)

为什么要这么做,并且为什么这种存储我们叫做循环队列?

我们一步步分析一下:

我们先按照我们一般的想法画出队列元素进出队的过程,例如队列元素出队

bb0fc885f2c5922e0cd8db8ccbd3d49d.png

这样的设想,也就是根据我们前面食堂排队的例子画出来的,但是我们可以清晰的看到,当a0出队后,a0后的元素全部需要前移,将空位补上,但我们在计算机中讲究性能二字,如何可以提高出队的性能呢?

循环队列就这样被设计出来了,我们如果不再限制队头一定在整个空间的最前面,我们的元素也就不需要集体移动了

e915ea3cf8ac27c42806da16c05542f1.png

问题一

这个时候我们就需要考虑这样的问题了:

① 如何为了解决只有一个元素的时候,队头和队尾重合使得处理变得麻烦?

  • 这时我们前面提到的两个指针就派上用场了(队头指针指向头元素的前一个位置,队尾指针指向队尾元素)当头尾指针相等的时候,代表是空队列

问题二

但是有一个大问题出现了 !

如果前面有空闲的空间还好说,一旦头元素前面没有空间,我们的队头指针就指向到了数组之外,也就会出现数组越界问题,这该怎么办呢?

我们可以看到,虽然我们的表头已经没有了任何空间,但是表的后半部分还有空余空间,这种现象我们称作假溢出,打个比方,接近上课你缓缓走进教室,看到只有前排剩下了两个位置,你总不会转身就走吧,当然可以去前排坐,只有实在没座位了,才考虑离开

我们可以做出这样一种比较可行的方案

  • 我们只需要将这个队列收尾连接起来,当后面的空间满后,接着从前面空出来的空间中进队,同样的,我们的表头指针也找到了可以指向的位置
  • 具体的连接方法,就是将date[0...maxSize] 的单元0认为是maxSize - 1

问题三

我们刚才也提到了,当表头指针和表尾指针相等的时候就解决了空队列的情况,但是在表满的情况下,你会发现,同样也满足表头表尾指针相等,那么又如何解决这个问题呢?(我们给出三种可行的解决方案)

  • A:设置一个标志变量flag,当front = rear的时,且flag = 0的时候为空,若flag = 1 的时候为队列满
  • B:设计一个计数器count统计当前队列中的元素数量,count == 0 队列空,count == maxsSize 队列满
  • C:保留一个存储空间用于区分是否队列已满,也就是说,当一个还空闲一个单元时候,我们就认为表已经满了

我们重点讲解 C 中的方法

我们根据这种方法可以总结出几个条件的运算式

  • 队列为满的条件:(rear+1) % MaxSize == front
  • 队列为空的条件:front == rear
  • 队列中元素的个数:(rear- front + maxSize) % MaxSize
  • 入队:rear = (rear + 1) % maxSize
  • 出队:front = (front + 1) % maxSize

(一) 顺序队列的类型定义

 #ifndef _SEQQUEUE_H_#define _SEQQUEUE_H_#include "Queue.h"​template <class T>class seqQueue:public Queue<T> {private://指向存放元素的数组 T &data;//队列的大小 int maxSize;//定义队头和队尾指针 int front, rear;//扩大队列空间 void resize();public: seqQueue(int initSize = 100);~seqQueue() {delete []data;}//清空队列 void clear() {front = rear = -1;}//判空bool empty() const {return front == rear;} //判满bool full() const {return (rear + 1) % maxSize == front;}//队列长度int size() const {(rear- front + maxSize) % maxSize;}//入队void enQueue(const T &x);//出队 T deQueue();//取队首元素T getHead() const; }; ​#endif 

(二) 初始化一个空队列

 template <class T>seqQueue<T>::seqQueue(int initSize) {if (initSize <= 0) throw badSize();data = new T[initSize];maxSize = initSize;front = rear = -1; }

(三) 入队

 template <class T>void seqQueue<T>::enQueue(const T &x) {//队满则扩容 if ((rear + 1) % maxSize == front) resize();//移动队尾指针 rear = (rear + 1) % maxSize;//x 入队 data[rear] = x;}

(四) 出队

 template <class T>T seqQueue<T>::deQueue() {//队列为空则抛出异常 if (empty()) throw outOfRange();//移动队尾指针 front = (front + 1) % maxSize;//x入队 return data[front];}

(五) 取队首元素

 template <class T>T seqQueue<T>::getHead() const {if (empty()) throw outOfRange();//返回队首元素,不移动队首指针 return data[(front + 1) % maxSize];}

(六) 扩大队列空间

 template <class T>void seqQueue<T>::resize() {T *p = data;data = new T[2 *maxSize];for(int i = 1; i < size(); ++i)//复制元素 data[i] = p[(front + i) % maxSize];//设置队首和队尾指针 front = 0; rear = size();maxSize *= 2;delete p;}

链队列

用链式存储结构表示队列我们叫做链队列,用无头结点的单链表表示队列,表头为队头,表尾为队尾,需要两个指针分别指向队头元素和队尾元素,这种存储结构的好处之一就是不会出现队列满的情况

a9ea6787be0b306591cd6a2fdb3b0d2a.png

(一) 顺序队列的类型定义

 #ifndef _LINKQUEUE_H_#define _LINKQUEUE_H_#include <iostream>#include "Queue.h"​template <class T>class linkQueue:public Queue<T> {private:struct node {T data;node *next;node (const T &x, node *N = NULL) {data = x;next = N;}node ():next(NULL){}~node () {} };node *front, *rear;public: linkQueue(){front = rear = NULL;};~linkQueue() {clear();}//清空队列 void clear();//判空bool empty() const {return front == NULL;} //队列长度int size() const;//入队void enQueue(const T &x);//出队 T deQueue();//取队首元素T getHead() const; };​#endif 

(二) 清空队列

 template <class T>void linkQueue<T>::clear() {node *p;//释放队列中所有节点 while(front != NULL) {p = front;front = front -> next;delete p;}//修改尾指针 rear = NULL;} 

(三) 求队列长度

 template <class T>int linkQueue<T>::size() const {node *p = front;int count = 0;while(p) {count++;p = p -> next;} return count;}

(四) 入队

 template <class T>void linkQueue<T>::enQueue(const T &x) {if(rear == NULL) front = rear = new node(x);else {rear -> next = new node(x);rear = rear -> next;}}

(五) 出队

 template <class T>T linkQueue<T>::deQueue() {//队列为空则抛出异常 if (empty()) throw outOfRange();node *p = front;//保存队首元素 T value = front -> data;front = front -> next;if (front == NULL)rear = NULL;delete p;return value;}

(六) 取队首元素

 template <class T>T linkQueue<T>::getHead() const {if (empty()) throw outOfRange();return front -> data; }

结尾:

如果文章中有什么不足,或者错误的地方,欢迎大家留言分享想法,感谢朋友们的支持!

如果能帮到你的话,那就来关注我吧!如果您更喜欢微信文章的阅读方式,可以关注我的公众号

在这里的我们素不相识,却都在为了自己的梦而努力 ❤
一个坚持推送原创开发技术文章的公众号:理想二旬不止

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

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

相关文章

c++ 不插入重复元素但也不排序_【每日一题】125. 对链表进行插入排序

关注我们获取更多计算机考研信息对链表进行插入&#xff0c;插入排序算法&#xff1a;插入排序是迭代的&#xff0c;每次只移动一个元素&#xff0c;直到所有元素可以形成一个有序的输出列表。每次迭代中&#xff0c;插入排序只从输入数据中移除一个待排序的元素&#xff0c;找…

怎么检查计算机网络是连接,怎么检测网络打印机是否与电脑连接成功【检测方法】...

想必不少宝宝和以前的小编一样&#xff0c;在用网络打印机的时候&#xff0c;有时候能打印&#xff0c;有时候却打印不了。那么如何 检测网络打印机是否与电脑连接成功?跟随小编往下看。系统反反复复告知“无法打印”&#xff0c;让工作本已繁忙的小修近乎奔溃! 那么&#xff…

python画菱形的代码_python绘制菱形

广告关闭 腾讯云11.11云上盛惠 &#xff0c;精选热门产品助力上云&#xff0c;云服务器首年88元起&#xff0c;买的越多返的越多&#xff0c;最高返5000元&#xff01;首先&#xff0c;将数据读入到python中&#xff0c;并绘制出生率和死亡率数据的散点图&#xff0c;代码如下&…

计算机实物知识需求市场调研,能力本位计算机维护论文

能力本位计算机维护论文1课程教学现状对于计算机专业学生来说&#xff0c;学会组装计算机系统&#xff0c;分析和解决计算机常见故障是计算机专业学生必须掌握的一项技能&#xff0c;学好本课程对将来就业有很大的帮助。然而&#xff0c;随着计算机技术的快速发展&#xff0c;本…

python爬取bilibili弹幕_python爬虫:bilibili弹幕爬取+词云生成

如果你懒得看下边的文字&#xff0c;我录了一个完整的教学视频在b站上。 我的B站教学&#xff1a;https://www.bilibili.com/video/av75377135?p2 工作原理 b站是提供弹幕接口的&#xff0c;所以我们的整体操作进行如下&#xff1a; 1.到B站获取cid2.将cid与网站固定格式进行链…

access vba 常量数组赋值_聊聊 VBA 数组的那些坑

为什么使用数组&#xff1f;1. 缩减工作薄文件大小&#xff0c;提高运行效率一般而言只是使用 Excel 的内置工作表函数&#xff0c;在运算方面还是很高效的&#xff0c;但有时因为一个单元格牵扯的计算太多&#xff0c;比如调用多单元格数据&#xff0c;对结果文本进行部分替换…

HTML文件可通过www进行传输,使用 zssh 进行 Zmodem 文件传输

Zmodem 最早是设计用来在串行连接(uart、rs232、rs485)上进行数据传输的&#xff0c;比如&#xff0c;在 minicom 下&#xff0c;我们就可以方便的用 Zmodem (说 sz 、rz 可能大家更熟悉)传输文件。只不过串口本身传输速度不快&#xff0c;文件大的话会让人有点崩溃。没有彻底把…

Linux下使用popen()执行shell命令

转载于&#xff1a;https://www.cnblogs.com/caosiyang/archive/2012/06/25/2560976.html 简单说一下popen()函数 函数定义 #include <stdio.h>FILE * popen(const char *command , const char *type ); int pclose(FILE *stream); 函数说明 popen()函数通过创建一个管道…

centos7安装python3.7.4_Centos7升级Python3.7.4

和大家技术分享一下当我们安装完成Centos7后&#xff0c;默认系统Python的版本为2.7.5。我们希望将Python升级到最新版本。 1、安装依赖项 yum install -y openssl-devel openssl-static zlib-devel lzma tk-devel xz-devel bzip2-devel ncurses-devel gdbm-devel readline-dev…

MyEclipse移动开发教程:迁移HTML5移动项目到PhoneGap(二)

MyEclipse开年钜惠 在线购买低至75折&#xff01;立即开抢>> 【MyEclipse最新版下载】 二、将文件从HTML5项目复制到PhoneGap项目中 1. 在HTML5 app项目的www/文件夹的资源中&#xff0c;单击右键&#xff0c;然后选择Copy。 从HTML5项目复制www资源2. 将资源粘贴到新Pho…

pb graph鼠标移上显示数据_Plotly数据可视化:离线版、微软vscode版的Python的基本作图...

1 介绍&#xff1a;1.1 Plotly 是一款用来做数据分析和可视化的在线平台&#xff0c;功能非常强大。1.2 Plotly是一个非常著名且强大的开源数据可视化框架&#xff0c;它通过构建基于浏览器显示的web形式的可交互图表来展示信息。1.3 具有多种语言python、javascript、matlab、…

centos安装无线网卡驱动_CentOS下显卡驱动安装的相关思考

背景&#xff1a;最近在安装显卡驱动&#xff0c;查找了一些网上的教程&#xff0c;但总感觉思路不够清晰&#xff0c;没办法弄清背后涉及的Linux原理&#xff0c;于是参考网上教程&#xff0c;并查阅了相关资料&#xff0c;希望能对显卡驱动安装作一个梳理&#xff0c;以做记录…

获取select被选中的option的值

<select id"select"> <option>绥江</option> <option>西江</option> <option>北江</option> <option>贺江</option> <option>新兴江</option> </select> $(funct…

红石32位cpu通用计算机,我的世界无命令方块32位红石电脑装置详解

来源&#xff1a;游戏园日期&#xff1a;2019-05-14 04:03:07我的世界无命令方块32位红石电脑装置详解。那下面给大家分享的是我的世界中的一个叫做机器编号为RSC-3230的红石电脑装置哦~有喜欢的顽疾啊不妨进来看看下的这个电脑哦~喜欢的话还可以下载下面的存档哦~本作品是一台…

python字符串字面量有哪四种定义方式_Python学习笔记(四)字符串型

字符串是 Python 中最常用的数据类型。我们可以使用引号(或")来创建字符串。 在最新的Python 3版本中&#xff0c;字符串是以Unicode编码的&#xff0c;也就是说&#xff0c;Python的字符串支持多语言。 创建字符串很简单&#xff0c;只要为变量分配一个值即可 View Code …

bzoj4380[POI2015]Myjnie dp

[POI2015]Myjnie Time Limit: 40 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 368 Solved: 185[Submit][Status][Discuss]Description 有n家洗车店从左往右排成一排&#xff0c;每家店都有一个正整数价格p[i]。有m个人要来消费&#xff0c;第i个人会驶过第a[i]个开始…

全国计算机等级考试用报名吗,全国计算机等级考试网上报名流程及考生报名使用说明...

全国计算机等级考试网上报名流程及考生报名使用说明附件&#xff1a;考生报名使用说明(一)注册账号和登录1)考生首次登录系统需要注册登录通行证&#xff0c;若考生有通行证账号&#xff0c;可以直接登录。2)考生也可使用其他账号登录&#xff0c;例如使用“QQ账号”登录。点击…

iptables nat实验_【零基础学云计算】LVS负载均衡群集之NAT模式搭建 (实践篇)...

实验原理图实验环境LVS调度器作为web服务器池的网关LVS服务器配置两块网卡分别连接内外网使用轮询&#xff08;rr&#xff09;调度算法LVS负载调度器网段规划 内网33网关&#xff1a;192.168.144.1 外网36&#xff1a;12.0.0.1web1 192.168.144.151web2 192.168.144.170nfs服务…

rs232串口驱动_RS232与RS485在性能上有啥区别和联系?老电工总结分析,一目了然...

串口是一种非常通用的设备接口&#xff0c;是仪器仪表设备常用的通信接口&#xff0c;常用于远程采集设备数据或者实现远程控制。串口的开发也比较简单&#xff0c;它是很多工程师最喜欢的接口之一。常见的串口协议有RS-232、RS-422、RS-485等&#xff0c;它是电子工程师面对的…

win7里面计算机叫什么,Win7电脑中的mrt.exe是甚么文件

咱们正在运用Win7体系的时分&#xff0c;只有咱们翻开使命办理便能够看失到有一个mrt.exe 步伐正在运转&#xff0c;也没有知叙mrt.exe 是甚么入程的&#xff0c;否不成以制止。这Win7电脑外的mrt.exe 是甚么文件呢&#xff1f;如今便随小编一同来看看电脑外的mrt.exe是甚么文件…