循环队列
为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。
相关条件
循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列是"空"还是"满"。解决这个问题的方法至少有两种:
- 另设一布尔变量以区别队列的空和满;
- 另一种方式就是数据结构常用的: 队满时:(rear+1)%n==front,n为队列长度(所用数组大小),由于rear,front均为所用空间的指针,循环只是逻辑上的循环,所以需要求余运算。如图1所示情况,队已满,但是rear(5)+1=6!=front(0),对空间长度求余,作用就在此6%6=0=front(0)。
类型定义采用环状模型来实现队列,各数据成员的意义如下:
front指定队首位置,删除一个元素就将front顺时针移动一位;
rear指向元素要插入的位置,插入一个元素就将rear顺时针移动一位;
count存放队列中元素的个数,当count等于MaxQSize时,不可再向队列中插入元素
代码如下
package queue
/**
循环队列:
front = (front+1)%size
rear = (rear+1)%size
length =(rear+maxsize-front)%size
ifFull:
(rear+1)%size =front
isEmpty:
rear=front
*/
import (
"fmt"
"testing"
)
type status int
const OK = 1
const FAIL = -1
type dataNode struct {
Name string
Age int8
}
type circularQueue struct {
maxSize int
Data []dataNode
front int
rear int
}
func (c *circularQueue) init(maxSize int) {
c.maxSize = maxSize
}
// isFull:判断队列是否已满
func (c *circularQueue) isFull() bool {
return (c.rear+1)%c.maxSize == c.front
}
// isEmpty:判断是否为空
func (c *circularQueue) isEmpty() bool {
return c.front == c.rear
}
// push:加入一个数据到队列
func (c *circularQueue) push(node dataNode) status {
if c.isFull() {
panic("判断队列满")
}
c.Data = append(c.Data, node)
c.rear = (c.rear + 1) % c.maxSize
return OK
}
// show:打印数据
func (c *circularQueue) show() {
if c.isEmpty() {
panic("队列为空")
}
for i := c.front; i < c.front+c.size(); i++ {
fmt.Println(c.Data[i])
}
}
// pop:弹出数据
func (c *circularQueue) pop(node dataNode) dataNode {
if c.isEmpty() {
panic("队列为空,无法弹出数据")
}
result := c.Data[c.front]
c.front = (c.front + 1) % c.maxSize
return result
}
// size:获取当前队列的大小
func (c *circularQueue) size() int {
return (c.rear + c.maxSize - c.front) % c.maxSize
}
func TestCircularQueue(t *testing.T) {
queue := circularQueue{}
queue.init(10)
queue.push(dataNode{Name: "张三", Age: 20})
queue.push(dataNode{Name: "李四", Age: 21})
queue.push(dataNode{Name: "李四", Age: 21})
queue.push(dataNode{Name: "李四", Age: 21})
queue.push(dataNode{Name: "李四", Age: 21})
queue.push(dataNode{Name: "李四", Age: 21})
queue.push(dataNode{Name: "李四", Age: 21})
queue.push(dataNode{Name: "李四", Age: 21})
queue.show()
}