1、什么是循环队列?
答:循环队列首先是一种线性的数据结构,也就是一个有序列表。第二它遵循先进先出的原则,即FIFO(first in first out)。而循环队列是为了弥补普通队列假性溢出的问题,而设计出来的一种更为高效的数据结构。
2、怎么用数组来模拟循环队列?
答:
- 队列的输出、输入是分别从前后端来处理,因此需要两个变量 front及 rear分别记录队列前后端的下标,front 会随着数据输出而改变,而 rear则是随着数据输入而改变。
- 定义maxSize 是该队列的最大容量。
- 明确怎么判断队列何时为空:当 rear==front的时候,这个判断条件不论是普通队列和循环队列都没有变化。
- 明确怎么判断队列何时已满:当(rear + 1) % maxSize == front 满]
- 初始时,rear 和 front 的初始值均为0。(而普通队列则初始值均为-1)
- 如何插入元素:首先你要先判读队列是否为空,接下来直接将元素插入到rear所在的位置,并将rear+1,不过要注意使用%取最大容量的余数。
public void addQueue(int n) {
if (isFull()) {
System.out.println("队列满,无法加入..");
return;}
arr[rear] = n;
rear = (rear + 1) % maxSize;}
- 如何弹出元素:
public int getQueue() {
if (isEmpty()) {
throw new RuntimeException("队列空~");}
int value = arr[front];
front = (front + 1) % maxSize;
return value;}
3、学到的知识点
- 类的初始化函数怎么写
def __init__(self,size=3):
#这里size如果没有写参数时,则默认初始化为3
self._size = size+1 #java代码中的maxSize
self._data = [0]*(size+1) #带self的变量都是类的属性
self._front = 0
self._rear = 0
- 循环队列初始化创建空队时,令front = rear = 0;
当队空时:front = rear
当队满时:front = rear 亦成立
因此需要约定当队列头指针在队尾指针rear的下一个位置上作为“满”的状态的标志。
即:
队满时: (rear+1)% maxsize = front
完整代码:
package com.xiaofan.Arrayqueue;
import java.util.Scanner;
public class CircleArrayQueue {
public static void main(String[] args) {
// 测试
System.out.println("测试循环数组");
ArrayQueue arr = new ArrayQueue(3);
char key = ' ';//获取用户输入
Scanner scanner = new Scanner(System.in);
boolean loop = true;
while(loop) {
System.out.println("s(show):显示队列");
System.out.println("e(exit):退出程序");
System.out.println("a(add):添加数据到队列");
System.out.println("g(get):从队列取出数据");
System.out.println("h(head):查看队列头的数据");
key = scanner.next().charAt(0);//
switch(key) {
case 's':arr.show();break;
case 'e':
scanner.close();
loop = false;
break;
case 'a':
System.out.println("输入一个数:");
int value = scanner.nextInt();
arr.addQueue(value);
break;
case 'g':
try {
//System.out.println("df");
int res = arr.getQueue();
System.out.printf("取出数据为%d",res);
}catch(Exception e) {
e.getMessage();
}
break;
case 'h':
try {
int res = arr.headQueue();
System.out.printf("队列的头数据为%d\n",res);
}catch(Exception e) {
e.getMessage();
}
break;
default:
break;
}
}
System.out.println("程序退出!");
}
}
class CirleArray{
private int maxSize;// 表示最大容量
private int front;//初始时指向0
private int rear;//初始时指向0
private int[] arr;
public CirleArray(int arrMaxSize) {
maxSize = arrMaxSize;
arr = new int [maxSize];
}
public boolean isFull() {
return (rear+1)%maxSize == front;
}
public boolean isEmpty() {
return rear == front;
}
public void addQueue(int n) {
if (isFull()) {
System.out.println("队列已满");
return;
}
arr[rear]=n;
rear = (rear + 1) % maxSize;
}
public int getQueue() {
if (isEmpty()) {
// 抛异常
System.out.println("队列为空");
throw new RuntimeException("队列为空,不能取值\n");
}
//1.先临时保存队列头部的值
//2.再将front后移,考慮取余
//3。再把临时保存的值返回
int value = arr[front];
front = (front + 1) % maxSize;
return value;
}
public void show() {
//int p = front + 1;
if (isEmpty()) {
System.out.println("队列为空,无法显示");
}
//从front开始遍历,遍历队列所有元素个数次
for (int i = front; i < front + size(); i++) {
System.out.printf("arr[%d]=%d\n", (i%maxSize), arr[i%maxSize]);
}
}
//求出当前队列的个数
public int size() {
return (rear+maxSize-front) % maxSize;
}
// 显示队列的头部
public int headQueue() {
if (isEmpty()) {
throw new RuntimeException("队列为空,没有数据");
}
return arr[front];
}
}