循环队列解决了,队列“假溢出”现象,提高了空间的利用效率。队列有两个指针域front和rear。
队列主要有以下操作:
(1)空队列时front=rear;入队列时,把数据放到rear所指的位置,然后rear向下移动一个
(2)当rear在向下移动一个就和front指向同一块区域(即rear+1=front)时,队列就已经装满了
(3)出队列时,获取并返回front所指的区域所存的数据,front向下移动一个,当front和rear指向同一块区域(即front=rear)时,队列为空
例如:
(f)图中p进入队列之后,队列已满,则s和t就进入队列失败。
接下来看代码
先封装一个queue类
package com.lqf.queue;
import java.util.Arrays;
public class Queue {
int front;
int rear;
char arr[];
public int getFront() {
return front;
}
public void setFront(int front) {
this.front = front;
}
public int getRear() {
return rear;
}
public void setRear(int rear) {
this.rear = rear;
}
public char[] getArr() {
return arr;
}
public void setArr(char[] arr) {
this.arr = arr;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(arr);
result = prime * result + front;
result = prime * result + rear;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Queue other = (Queue) obj;
if (!Arrays.equals(arr, other.arr))
return false;
if (front != other.front)
return false;
if (rear != other.rear)
return false;
return true;
}
public Queue(int front, int rear, char[] arr) {
super();
this.front = front;
this.rear = rear;
this.arr = arr;
}
public Queue() {
super();
}
@Override
public String toString() {
return "Queue [front=" + front + ", rear=" + rear + ", arr=" + Arrays.toString(arr) + "]";
}
}
再建立一个操作类
public class Op {
private static int n = 5;
// 遍历
public int traverse(Queue q) {
int count = 0;
if (q.front != q.rear) {//栈中有元素
int p = q.front;// 循环变量
while (p % n != q.rear) {//从队首遍历到队尾
p = (p + 1) % n;
count++;
}
}
return count;
}
// 获取队首元素
public char getHead(Queue q) {
char e = 0;
if ((q.front + 1) % n != q.rear) {//栈中还有元素
e = q.arr[q.front];
System.out.println("success.");
} else {//栈空
System.out.println("the queue is empty.");
}
return e;
}
// 出队列并返回队首元素
public char dequeue(Queue q) {
char e = 0;
if (q.front != q.rear) {//栈中还有元素
e = q.arr[q.front];
q.front = (q.front + 1) % n;//front向下移动一个
System.out.println("success.");
} else {//栈空
System.out.println("the queue is empty.");
}
return e;
}
// 入队列
public void enqueue(Queue q) {
if ((q.rear + 1) % n != q.front) {//栈中还有空间
System.out.print("please enter the data:");
Scanner sc = new Scanner(System.in);
q.arr[q.rear] = sc.next().charAt(0);
q.rear = (q.rear + 1) % n;//rear向下走一个
System.out.println("success.");
} else {//栈满
System.out.println("the queue is full.");
}
}
// 初始化
public void initialize(Queue q) {
q.arr = new char[n];//初始化数据域
q.front = q.rear = 0;
System.out.println("success.");
}
}
对方法进行测试
public class Test {
public static void main(String[] args) {
int a;// 操作码
Queue Q = new Queue();
Op op = new Op();
Scanner sc = new Scanner(System.in);
System.out.println("1.initialize");
System.out.println("2.enqueue");
System.out.println("3.dequeue");
System.out.println("5.traverse");
while (true) {
System.out.print("please enter operation code:");
a = sc.nextInt();
switch (a) {
case 1:
op.initialize(Q);
break;
case 2:
op.enqueue(Q);
break;
case 3:
char b = op.dequeue(Q);
System.out.println(b);
break;
case 4:
char c = op.getHead(Q);
System.out.println(c);
break;
case 5:
int count = op.traverse(Q);
System.out.println(count);
break;
default:
System.out.println("error.");
break;
}
}
}
}
空间为n,只能存n-1个数据
这里以最开始的例子为例,运行一下程序(注:程序中的空间个数n=5,比图中的空间少一个)