[循环队列]使用原因与注意事项

原创 2015年07月11日 00:24:32
   问题描述:循环队列是一般队列的变种吧,就是将队列首尾相连了,貌似这样就不必考虑队列满而无法使用了,因为到了队列尾又会循环回到队列首。在嵌入式底层代码实现中,一些串行端口数据特别是串口,用到循环队列的情况还是蛮多的。当然,这只是一种数据结构,用在哪里都得看具体用途和是否能带来好处。为了更深一步的对这一结构的了解,进行了下整理和学习。
   循环队列:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。这个应当是比较成熟的定义了,简洁了当。像是一条蛇咬住自己的尾巴,而且蛇腔里面可以填充东西的感觉。
    为什么用循环队列:主要是为了克服“假溢出”情况,系统作为队列用的存储区还没有满,但队列却发生了溢出,我们把这种现象称为"假溢出"。其实就是因为队列的first in first out特质所引起的,队列为获得first in first out特质,一般需要两个指针,一个称为“头指针”,一个称为“尾指针”,头指针用于在队列头部读出元素尾指针用于在队列尾部插入新元素,先进去队列的元素位于队列的头部。对于使用顺序队列情况,随着队列尾部不断插入新元素,尾指针最终会指向分配给队列的最后的内存地址,当再有新元素要插入时,此时队列尾部已经无法插入新元素了。而头指针由于有元素出队列,队列内存空间的前面一部分其实还是空的,因此就造成了“假溢出”这种情况。循环队列就是为解决该问题的。(当然,解决假溢出还可以将队列元素做平移,但感觉使用循环队列会有更高的效率)。
    循环队列弊端:循环队列空和满时都是头指针等于尾指针,因此对于队列空和满的判断需要在代码中加以区别,有三种方式:一是另设一布尔变量来区别队列的空和满。二是少用一个元素的空间,每次入队前测试入队后头尾指针是否会重合,如果会重合就认为队列已满。三是设置一计数器记录队列中元素总数,不仅可判别空或满,还可以得到队列中元素的个数。
    循环队列类型定义:
#define QueueSize 100 //应根据具体情况定义该值
typedef char DataType; //DataType的类型依赖于具体的应用
typedef struct{
int front; //头指针,队非空时指向队头元素
int rear; //尾指针,队非空时指向队尾元素的下一位置
int count;//计数器,记录队中元素总数
DataType data[QueueSize];
}CirQueue;
    循环队列的基本运算:
1. 队列置空:
void InitQueue(CirQueue *Q)
{
Q->front=Q->rear=0;
Q->count=0; //计数器置0
}
2. 队列判空:
int QueueEmpty(CirQueue *Q)
{
return Q->count==0; //队列无元素为空
}
3. 判断队列是否满:
int QueueFull(CirQueue *Q)
{
return Q->count==QueueSize; //队中元素个数等于QueueSize时队满
}
4. 元素队列尾部入队:
void EnQueue(CirQueue *Q,DataType x)
{
if(QueueFull(Q))
Error("Queue overflow"); //队满上溢
Q->count ++; //队列元素个数加1
Q->data[Q->rear]=x; //新元素插入队尾
Q->rear=(Q->rear+1)%QueueSize; //循环意义下将尾指针加1
}
5. 元素从队列头部出队列:
DataType DeQueue(CirQueue *Q)
{
DataType temp;
if(QueueEmpty(Q))
Error("Queue underflow"); //队空下溢
temp=Q->data[Q->front];
Q->count--; //队列元素个数减1
Q->front=(Q->front+1)%QueueSize; //循环意义下的头指针加1
return temp;
}
    循环队列使用总结:优点是逻辑判断简单,执行程序实现容易。 缺点是执行时重复比较太多,效率不一定高,大型系统节点较多时不宜采用(重复比较太多的问题暂时未碰到,队列用来传递FIFO消息的情况较多,重复比较问题以后碰到再补充)。
版权声明:本文为博主原创文章,未经博主允许不得转载。

C++标准库---vector使用注意事项

使用vector需要注意的地方 1.vector支持随机存取,因此你只要知道元素的位置,可以在常数时间内存取任何一个元素; 2.在末端附加或删除元素,vector的性能相当好,但是在前端或中部安插...
  • lanzhihui_10086
  • lanzhihui_10086
  • 2014年11月29日 12:34
  • 1122

Java数组实现循环队列的两种方法

用java实现循环队列的方法: 1、增加一个属性size用来记录目前的元素个数。目的是当head=rear的时候,通过size=0还是size=数组长度,来区分队列为空,或者队列已满。 2...
  • takemetofly
  • takemetofly
  • 2015年08月29日 15:58
  • 1984

循环队列问题

1.   一循环队列,队头指针为front,队尾指针为rear,循环队列长度为N,其队内有效长度为_______ 2....
  • seekcreation
  • seekcreation
  • 2014年06月05日 16:31
  • 1377

队列的顺序存储结构——循环队列 图解和代码实现

队列的顺序存储结构——循环队列 循环队列的长度为(rear-front+QueueSize)%QueueSize 队空的条件: front=rear 队满的条件是: (rear+1)%Queue...
  • ggxxkkll
  • ggxxkkll
  • 2013年03月11日 23:07
  • 9831

队列的顺序存储实现—循环队列

队列(queue)是一种只允许在一端插入元素,而在另一端删除元素的线性表。它是一种先进先出(First In First Out,FIFO)的线性表。我们把允许插入的一端称为队尾,允许删除元素的一端称...
  • chewbee
  • chewbee
  • 2015年04月17日 21:37
  • 2231

Android之循环队列操作

队列特性:先进先出(FIFO)——先进队列的元素先出队列。 来源于我们生活中的队列(先排队的先办完事)。 下面以一个简单的例子实现循环队列的操作。 1.新建Android应用程序 ...
  • bingdianlanxin
  • bingdianlanxin
  • 2015年02月02日 21:55
  • 1595

队列---循环队列与链队列比较

对于循环队列与链队列的比较,可以从两方面来考虑:1、从时间上,其实它们的基本操作都是常数时间,即都为0(1)的,不过循环队列是事先申请好空间,使用期间不释放,而对于链队列,每次申请和释放结点也会存在一...
  • will130
  • will130
  • 2015年10月21日 23:11
  • 960

C语言实现使用动态数组实现循环队列

我在上一篇博客《C语言实现使用静态数组实现循环队列》中实现了使用静态数组来模拟队列的操作。由于数组的大小已经被指定,无法动态的扩展。所以在这篇博客中,我换成动态数组来实现。动态数组可以不断开辟内存空间...
  • CHENYUFENG1991
  • CHENYUFENG1991
  • 2016年03月07日 09:18
  • 4569

Java 循环队列的实现

队列概念   队列(Queue)是限定只能在一端插入、另一端删除的线性表。允许删除的一端叫做队头(front),允许插入的一端叫做队尾(rear),没有元素的队列称为“空队列”。   队列具有先进...
  • qq_34405283
  • qq_34405283
  • 2017年06月03日 18:09
  • 182

数据结构之队列(设计并实现一个自己的队列:循环数组+扩容策略)

1、队列介绍 队列是一种由有次序关系的数据项构成的数据结构,只能在一端(称为队尾)插入数据项,而从另一端(称为队头)移除数据项。 位于队列中队头位置的数据项称为首数据项。 2、队列实现分析 实现队列有...
  • zj1316151417
  • zj1316151417
  • 2017年06月10日 21:34
  • 394
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[循环队列]使用原因与注意事项
举报原因:
原因补充:

(最多只允许输入30个字)