关于循环队列的一些讲解
2012-08-06 00:00
676 查看
前面讲到了队列的“假溢出”,解决假溢出的办法就是后面满了,就再从头开始,也就是头尾相接的循环。我们把队列的这种头尾相接的顺序存储结构称为循环队列。
比如昨天的例子,rear可以改为指向下标为0的位置,这样就不会造成指针指向不明的问题了。
但是如果继续进行入队操作的话,比如继续插入a6、a7,则rear指针就与front指针重合,同时指向下标为2的位置。
此时问题又出来了,我们刚才说,空队列时,等于rear,现在当队列满时,也是from等于rear,那么如何判断此时的队列究竟是空还是满呢?
办法一是设置一个标志变量flag,当front == rear,且flag = 0时为队列空,当front == rear,且flag= 1时为队列满。
办法二是当队列空时,条件就是from = rear,当队列满时,我们修改其条件,保留一个元素空间。也就是说,队列满时,数组中还有一个空闲单元。 如下图所示,我们就认为此队列已经满了,也就是说,我们不允许上图情况出现。
我们来讨论第二种方法,由于rear可能比front大,也可能比front小,所以尽管它们只相差一个位置时就是满的情况,但也可能是相差整整一圈。所以若队列的最大尺寸为QueueSize,那么队列满的条件是(rear+1) %QueueSize == front (取模“%的目的就是为了整合rear与front大小为一个问题)。
比如上面这个例子, QueueSize = 5,当 front=0,而 rear=4, (4+1) %5 = 0,所以此时队列满。再比如,front = 2而rear =1。(1 + 1) %5 = 2,所以此时 队列也是满的。而对于下图, front = 2而rear= 0, (0+1) %5 = 1,1!=2,所以此时队列并没有满。
另外,当rear > front时,此时队列的长度为rear—front。但当rear
(rear—front + QueueSize) % QueueSize
有了这些讲解,现在实现循环队列的代码就不难了。具体的例子程序可以参照前面说的顺序队列。
单是顺序存储,若不是循环队列,算法的时间性能是不高的,但循环队列又面临着数组可能会溢出的问题,所以我们还需要研究一下不需要担心队列长度的链式存储结构。
栈的定义与大概理解
栈的抽象数据类型ADT
顺序栈:栈的顺序存储结构
顺序栈的进栈操作
顺序栈的出栈操作
获取顺序栈的栈顶元素
链栈:栈的链式存储结构
链栈的进栈操作
链栈的初始化与遍历
链栈的出栈操作
链栈的置空操作与判断链栈是否为空
为什么要使用栈这种数据结构
递归,栈的重要应用之一
栈是如何实现递归的
接触后缀表达式(逆波兰表示法)
图解后缀表达式的计算过程
将中缀表达式转化为后缀表达式
开始学习队列这个数据结构
队列的抽象数据类型ADT
顺序队列:队列的顺序存储结构
顺序队列的入队操作
顺序队列的出队操作
顺序队列置空与判断操作
队列顺序存储结构的不足
关于循环队列的一些讲解
链队列:队列的链式存储结构
链队列的初始化操作
链队列的入队操作
链队列的出队操作
补完链队列的其它常见操作
循环队列与链队列的优劣势
比如昨天的例子,rear可以改为指向下标为0的位置,这样就不会造成指针指向不明的问题了。
但是如果继续进行入队操作的话,比如继续插入a6、a7,则rear指针就与front指针重合,同时指向下标为2的位置。
此时问题又出来了,我们刚才说,空队列时,等于rear,现在当队列满时,也是from等于rear,那么如何判断此时的队列究竟是空还是满呢?
办法一是设置一个标志变量flag,当front == rear,且flag = 0时为队列空,当front == rear,且flag= 1时为队列满。
办法二是当队列空时,条件就是from = rear,当队列满时,我们修改其条件,保留一个元素空间。也就是说,队列满时,数组中还有一个空闲单元。 如下图所示,我们就认为此队列已经满了,也就是说,我们不允许上图情况出现。
我们来讨论第二种方法,由于rear可能比front大,也可能比front小,所以尽管它们只相差一个位置时就是满的情况,但也可能是相差整整一圈。所以若队列的最大尺寸为QueueSize,那么队列满的条件是(rear+1) %QueueSize == front (取模“%的目的就是为了整合rear与front大小为一个问题)。
比如上面这个例子, QueueSize = 5,当 front=0,而 rear=4, (4+1) %5 = 0,所以此时队列满。再比如,front = 2而rear =1。(1 + 1) %5 = 2,所以此时 队列也是满的。而对于下图, front = 2而rear= 0, (0+1) %5 = 1,1!=2,所以此时队列并没有满。
另外,当rear > front时,此时队列的长度为rear—front。但当rear
(rear—front + QueueSize) % QueueSize
有了这些讲解,现在实现循环队列的代码就不难了。具体的例子程序可以参照前面说的顺序队列。
单是顺序存储,若不是循环队列,算法的时间性能是不高的,但循环队列又面临着数组可能会溢出的问题,所以我们还需要研究一下不需要担心队列长度的链式存储结构。
延伸阅读
此文章所在专题列表如下:栈的定义与大概理解
栈的抽象数据类型ADT
顺序栈:栈的顺序存储结构
顺序栈的进栈操作
顺序栈的出栈操作
获取顺序栈的栈顶元素
链栈:栈的链式存储结构
链栈的进栈操作
链栈的初始化与遍历
链栈的出栈操作
链栈的置空操作与判断链栈是否为空
为什么要使用栈这种数据结构
递归,栈的重要应用之一
栈是如何实现递归的
接触后缀表达式(逆波兰表示法)
图解后缀表达式的计算过程
将中缀表达式转化为后缀表达式
开始学习队列这个数据结构
队列的抽象数据类型ADT
顺序队列:队列的顺序存储结构
顺序队列的入队操作
顺序队列的出队操作
顺序队列置空与判断操作
队列顺序存储结构的不足
关于循环队列的一些讲解
链队列:队列的链式存储结构
链队列的初始化操作
链队列的入队操作
链队列的出队操作
补完链队列的其它常见操作
循环队列与链队列的优劣势
相关文章推荐
- 关于循环队列的一些讲解
- 关于循环队列的一些讲解
- 关于循环队列取模的一些想法
- 关于C语言循环结构的一些习题
- 关于platform_device一些讲解
- 循环队列的一些计算
- 关于ArrayBlockingQueue队列的一些问题
- 关于循环语句打印形状的一些思考
- 在网上摘的,留着用吧,关于自定义控件的一些讲解 surfaceview
- 关于javascript的一些知识以及循环详解
- RabbitMQ中关于消息队列的一些概念
- 体验C#——关于一些循环语句
- 关于pl/sql中流程控制和循环的一些总结
- 关于 双向循环链表 的一些基础程序
- L的java学习笔记——关于运算符和循环的一些重点
- 关于结构体的一些讲解,恳请大家指正
- 关于java.awt.datatransfer包的一些讲解
- 关于JAVA的Scanner(System.in)循环输入的一些问题与解决
- 关于for循环遇到的一些错误
- 关于TextView的一些初步讲解