提示:居上位而不骄,在下位而不忧。故乾坤因其时而惕,虽危无咎矣

文章目录

  • 前言
  • 一、循环队列
    • 1.1定义
    • 1.2 基本操作
    • 1.3 判断条件
      • 1.3.1 队空
      • 1.3.2 队满
        • 1、牺牲一个单元用来区分队空与队满,即队头指针在队尾指针的下一个位置作为作为队满的标志
        • 2、类型中增加表示元素个数的变量
        • 3、类型中新增加tag数据成员,以区分时队满还是队空
  • 二、结构体
  • 三、关键代码讲解
    • 3.1、打印循环队列
    • 3.2、初始化
    • 3.3、入队
    • 3.4 出队
  • 四、可执行代码汇总
  • 总结:关于运行截图的分析
  • 总结

前言

提示:本篇文章主要写的是循环队列 承接上文顺序队列:
所谓循环队列其实也就是在 这个F同学与R同学跑步相当于时你追我赶的形式 当他们相遇的时候到底是R多走了一圈(队满)还是F 又重新追了上来(队空) 屁股上沾黄泥 说不清了,于是我们就告诉R等你,没有超过F同学 但是已经可以看到他后背的时候 你就喊 (rear+1)/maxsize=front 此时我们就知道你比他多跑一圈了


一、循环队列

1.1定义

把存储队列元素的表从逻辑上视为一个环,称为循环队列
怎么体现循环性呢?当rear 值可能超过MAX的时候 又有空位置 此时一定是数组中的小下标 我们rear%MAX 来使用小下标

1.2 基本操作

初始化:Q.front=Q.rear=0;
队首指针进1:Q.front=(Q.front+1)%MaxSize
队尾指针进1:Q.rear=(Q.rear+1)/MaxSize
队列长度:(Q.rear-Q.front+MaxSize)%Maxsize

1.3 判断条件

1.3.1 队空

Q.front==Q.rear

1.3.2 队满

1、牺牲一个单元用来区分队空与队满,即队头指针在队尾指针的下一个位置作为作为队满的标志

队满条件:(Q.rear+1)%MaxSize==Q.front
队空条件:Q.front == Q.rear
队列中元素的个数:(Q.rear-Q.front+MaxSize)% MaxSize

2、类型中增加表示元素个数的变量

每入队一个元素则变量计数器加一 出队一个则变量计数器减一
队空:Q.size==0;
队满:Q.size == MaxSize

3、类型中新增加tag数据成员,以区分时队满还是队空

思想设置一个tag 当进队列的时候,赋值tag=1 当出队的时候赋值tag=0,
因为只有出队的时候 tag = =0&&Q.front = = Q.rear的时候时候才可能为空
至于当入队tag = = 1&&Q.front==Q.rear 的时候才可能为满
tag等于0时 若是因为删除导致Q.front = =Q. rear 则为队空
tag等于1时 若是插入导致Q.front == Q.rear 则为队满

二、结构体

这里结构体我们选择比较大众化的详情请见 一种,至于原因容我想想怎么胡编乱造

//静态顺序队列
typename struct{ElemType data[MAX];//int size;这里也是可以不需要的  因为判满用的的是rear==MAX; int front;//因为限定了  只能从一端插入一端出  所以相较于 int rear;// 其实这两个变量就是标记空白取余的数组下标
} Queue;

三、关键代码讲解

3.1、打印循环队列

这个顺序之中要注意一点就是front 并不一定比rear 小的 就像跑步一样
尽管rear跑的比front多 但是位移量可能并没有front多(我写的时位移量 不是距离量)
所以要如何写这个打印队列? 发动你聪明的小脑袋瓜
特点是循环队列中每一个下标只能出现一次,写到这里我必须给自己一个糖了 尽管我不知道我的想法对不对 (事实上运行之后确实是没有问题)

void PrintQueue(Queue &Q){cout<<"此时队列中的元素是(左边是队头)";for(int i=Q.front;i!=Q.rear;i=((1+i)%MAX)){cout<<Q.base[i]<<" ";} cout<<endl;
}

3.2、初始化

直接赋值应该没有什么难度吧。。。

bool InitQueue(Queue &Q){Q.front=0;Q.rear=0;
}

3.3、入队

还有进队列就是要判断此时是否队列满 栈若是未满 我们在何处填入这个值呢 这个是有讲究的 rear 坐标的唯一性 因为是循环 所以不能一直++ 一直++ 如何实现循环 理解循环实现的原理 甚至书都不需要看 就可以打出来 这里使用角标的时候是base[rear%MAX]
还是base[rear] 取余不取余没有区别 但是下面移动指针的时候一定要一定要取余 否则你就构不成循环

bool EnQueue(Queue &Q,ElemType &x){if((Q.rear+1+MAX)%MAX==Q.front){printf("队列已满");return false; }Q.base[Q.rear%MAX]=x; Q.rear=(Q.rear+1)%MAX;cout<<"进行进队列操作之后";PrintQueue(Q);return true;
}

3.4 出队

DeQueue为弹出操作 ,弹出之前需要判断是否已经为空 弹出不需要释放空间
但是弹出是否需要像rear一样front%MAX? 通过画图可以很明显感觉到也是需要%的

bool DeQueue(Queue &Q,ElemType &x){if(Q.front==Q.rear) return false;else{x=Q.base[(Q.front%MAX)]; //这里依然是先用再加 Q.front=(Q.front+1)%MAX; }cout<<"进行出队列之后的操作是";PrintQueue(Q); return true;
}

四、可执行代码汇总

// InitQueue(&Q):初始化队列 构建一个空队列Q
// QueueEmpty(Q):判断队列是否为空若是队列为空 返回true  否则返回false
// EnQueue(&Q,x) 若是队列未满 则加入使之称为新的那个队尾
// DeQueue(&Q,&x) 出队 若是队列非空 删除队头元素,并用x 返回
// GetHead(Q,&x):读队头元素 若是未空,则将队头元素赋值给x
#include<bits/stdc++.h>
#define ElemType int
#define OK 1
#define ERROR 0
#define MAX 3
using namespace std;
typedef struct Queue{ElemType base[MAX];int front;int rear;
}Queue;
//这个顺序之中要注意一点就是front 并不一定比rear 小的 就像跑步一样
//尽管rear跑的比front多 但是位移量可能并没有front多(我写的时位移量  不是距离量)
//所以要如何写这个打印队列? 发动你聪明的小脑袋瓜
//特点是循环队列中每一个下标只能出现一次,写到这里我必须给自己一个糖了 尽管我不知道我的想法对不对
void PrintQueue(Queue &Q){cout<<"此时队列中的元素是(左边是队头)";for(int i=Q.front;i!=Q.rear;i=((1+i)%MAX)){cout<<Q.base[i]<<" ";} cout<<endl;
}
bool InitQueue(Queue &Q){Q.front=0;Q.rear=0;
}
bool QueueEmpty(Queue Q){if(Q.front==Q.rear) return true;else return false;
}
//还有进队列就是要判断此时是否队列满  栈若是未满 我们在何处填入这个值呢 这个是有讲究的 rear 坐标的唯一性 因为是循环 所以不能一直++
bool EnQueue(Queue &Q,ElemType &x){if((Q.rear+1+MAX)%MAX==Q.front){printf("队列已满");return false; }Q.base[Q.rear%MAX]=x; Q.rear=(Q.rear+1)%MAX;cout<<"进行进队列操作之后";PrintQueue(Q);return true;
}
//DeQueue为弹出操作 ,弹出之前需要判断是否已经为空  弹出不需要释放空间
//但是弹出是否需要像rear一样front%MAX? 通过画图可以很明显感觉到也是需要%的
bool DeQueue(Queue &Q,ElemType &x){if(Q.front==Q.rear) return false;else{x=Q.base[(Q.front%MAX)]; //这里依然是先用再加 Q.front=(Q.front+1)%MAX; }cout<<"进行出队列之后的操作是";PrintQueue(Q); return true;
}
bool GetHead(Queue Q,ElemType &x){if(Q.front==Q.rear) return false;else{x=Q.base[Q.front]; //注意这里不是减减,不能改变topd的位置指向 }return true;
}
void menu(){cout<<"请选择你要进行的操作"<<endl;cout<<"1、判断队列是否为空 2、进队列 3、出队列 "<<endl;cout<<"4、获得队列顶的值  5、展示队列中的内容 6、退出"<<endl;
}
int main(){Queue Q;ElemType x;InitQueue(Q);int choice;while(1){menu();  cin>>choice;if(6==choice) break;switch(choice){case 1:{if(QueueEmpty(Q)){cout<<"队列为空"<<endl;}else{cout<<"队列不为空"<<endl;} break;}case 2:{cout<<"请输入你要入队列的值"<<endl; cin>>x; EnQueue(Q,x);break;}case 3:{DeQueue(Q,x);break;}case 4:{GetHead(Q,x);cout<<"此时队列顶元素是"<<x;break;}case 5:{PrintQueue(Q);break;} default:break;}} return 0;
}

总结:关于运行截图的分析

这里放一个自己演算的’草‘图 因为我的MAX设置为三


我们判断自己是否成功 首先要先把队列填满 填满之后rear 指向的就是最后一个位置 我们在弹出队中的元素 此时保证队中是有空余的,此时在填入 若是可以添加成功 说明构成了循环 否则就没有构成循环

总结

若是文章对你的提升由哪怕一点帮助的话 请答应我 不要吝啬你的点赞评论 你的鼓励对作者是一种莫大的鼓励转载请告知哪一部分我检查一下

考研数据结构之循环队列相关推荐

  1. mysql循环队列_数据结构:循环队列

    数据结构:循环队列 写在前面 数组表示的问题 对于队列最好的方法是使用链表实现,因为对于数组来说,队列可能会出现下面这种情况: 如图所示,不可以继续添加元素,否则会造成数组越界而遭致程序出错.然而此时 ...

  2. java循环的概念_Java数据结构之循环队列简单定义与用法示例

    本文实例讲述了Java数据结构之循环队列简单定义与用法.分享给大家供大家参考,具体如下: 一.概述: 1.原理: 与普通队列的区别在于循环队列添加数据时,如果其有效数据end == maxSize - ...

  3. java环形队列测试,JAVA数据结构之循环队列的实现

    1.循环队列CircleQueue类的实现代码如下所示: public class CircleQueue { private Object[] array; private int capacity ...

  4. 【数据结构】循环队列

    循环队列 入队判断是否满. 出队判断是否空 队列的有效空间[head,Tail) 入队列:把新的元素放在tail对应的下标上,同时tail++ o(1) 当Tail到达数组的末尾时,Tail从0开始 ...

  5. C++数据结构:循环队列基本运算的实现

    实验要求 编写一个程序,以菜单形式实现循环队列的各种基本运算,并在此基础上设计一个主程序,完成如下功能: (1)初始化空队列 (2)建立循环队列 (3)入队 (4)出队 (5)判断队列是否为空,为空返 ...

  6. 循环队列的java结构_java数据结构之循环队列(数组实现)

    package com.ws.队列.数组环形队列; //环形数组队列 //判断满:尾+1%队列长度==头 //添加数据:要(尾+1)%数组长度 //取出数据:要(头+1)%数组长度 因为这两个都是循环 ...

  7. 【数据结构与算法】循环队列和链队列的比较

    前言 本文原本是一篇随感+笔记,被翻出来后就整理发了博客. 不曾想能上搜索头条,既如此,决定更新一下,加上必要的阐释,避免影响有需求的读者. (我这么理解大家,如果有需要的话,是不是可以考虑点个赞或者 ...

  8. 王道数据结构课代表 - 考研数据结构 第三章 栈和队列 究极精华总结笔记

    本篇博客是考研期间学习王道课程 传送门 的笔记,以及一整年里对数据结构知识点的理解的总结.希望对新一届的计算机考研人提供帮助!!!   关于对 栈和队列 章节知识点总结的十分全面,涵括了<王道数 ...

  9. 循环队列–C语言实现–数据结构

    循环队列–C语言实现–数据结构 目录 循环队列C语言实现数据结构 目录 一 要求 二 循环队列 三 循环队列的算法设计 1 建立循环队列 2 置空队列 3 入队 4 出队 5 打印队 四 程序 1 程 ...

最新文章

  1. linux系统版本间的区别是什么?内核又是什么
  2. 面试彩蛋1:斐波那契数列用递归函数、循环函数实现
  3. Spring Boot Profile使用详解及配置源码解析
  4. java 批量处理 示例_Java中异常处理的示例
  5. CentOS7开发环境搭建(2)
  6. idea 2020.2 如何设置classpath_开发属于自己的第一款IDEA插件!
  7. 《团队-爬取豆瓣电影TOP250-设计文档》
  8. 云平台中节点异常如何考虑迁移因素
  9. js去掉所有html标记
  10. c语言平 ac自动机,多模式串匹配之AC自动机算法(Aho-Corasick算法)简介与C语言程序实现源码参考...
  11. android 怎样扩大内存卡,SD卡变RAM 增加虚拟内存方法
  12. 快手科技音视频技术亮相ChinaMM 首次公开多媒体传输协议KTP
  13. 2021-05-12 MongoDB面试题 应该启动一个集群分片(sharded)还是一个非集群分片的 MongoDB 环境
  14. 我的电脑中多了CD驱动器怎么办
  15. 15/18位身份证号码验证的正则表达式总结(详细版)
  16. 在springboot中使用PageHelper(mybatis的分页插件) 以及自定义分页
  17. 聊一下测试工程师的面试与招聘【转载自安大叔】
  18. 从SPACE矩阵,看5G究竟是否在走向成功?
  19. LeetCode《算法入门》刷题笔记(31 题全)
  20. IT行业里的热门技术

热门文章

  1. 图片加载和它的内存们
  2. 使用素描图像识别人脸
  3. Python的 yield用法
  4. 说说越婢加术汤(黄煌)
  5. C语言:srand函数与rand函数的使用(纯干货)【易懂】
  6. mos管的rc吸收电路计算_一种反激式开关电源中MOS管的RC吸收电路的制作方法
  7. Treap + FHQ Treap
  8. Android系统分区介绍
  9. 物联网中常提到的M2M究竟是什么?
  10. 利用R语言对贷款客户作风险评估