前言
提示:看了老师视频有些疑惑:这里我自己看法
主要参考了尚硅谷韩老师视频和大话数据结构p115
一、直接上代码
package com.QueueStudy;
/**
* 解决arrayQueue的问题
*
* 1)目前数组使用一次就不能用,没有达到复用的效果
* 2)将这个数组使用算法,改进成一个环形的队列取模:%
*/
public class CircleArrayQueue {
private int maxSize;//表示数组的最大容量
private int front;//指向队列头
/**
* 为啥队尾这样设计呢?
* 如果指向队尾元素那么判断队列为空和当队列为1个元素
* 条件都为front == rear 不好处理了
*
* 所以我们约定rear指向队尾的下一个元素
*/
private int rear;//队列尾的下一个元素
private int[] arr;//该数据用于存放数据,模拟队列
public CircleArrayQueue(int maxSize) {
this.maxSize = maxSize;
this.arr = new int[maxSize];
front = 0;//指向队列头部,分析出front是指向队列头的前一个位置。
rear = 0;//指向队列尾,指向队列尾的数据(即就是队列最后一个数据)
}
//判断队列是否满
/**
* 方法一:front == rear % maxSize
* 这个和判断队列为空一样了(front == rear 等价于front == rear % maxSize)
* 你还得另外这是flag进行区分(具体查看大话数据结构p115)
*
* 方法二:我么约定队列满了情况下其实还有1个空位
* 这样判断队列满 (rear + 1)%maxSize == front
* 和队列为空区分
* @return
*/
public boolean ifFull(){
return (rear + 1)%maxSize == front;
}
//判断队列是否为空
public boolean isEmpty(){
return rear == front;
}
//添加数据到队列
/**
* (rear + 1) % maxSize 中取模 maxSize目的走到队列尾部能够返回0位置
* rear + 1 为了rear指向队尾下一个元素(这是我们之前约定)
* @param n
*/
public void addQueue(int n){
if (ifFull()){
System.out.println("队列满,不能加入数据");
return;
}
arr[rear] = n;
rear = (rear + 1) % maxSize;
}
//获取队列的数据,出队列
public int getQueue(){
if (isEmpty()){
throw new RuntimeException("队列空,不能取出数据");
}
int temp = arr[front];
front = (front + 1) % maxSize;
return temp;
}
//显示队列的所有数据
/**
* i % maxSize 取数据能够返回0位置
*/
public void show(){
if (isEmpty()){
System.out.println("队列空的,没有数据");
}
for (int i = front;i < front + getSize();i++){
System.out.print(arr[i % maxSize] + " ");
}
}
//显示队列的头数据,注意不是取出数据
public int headQueue(){
if (isEmpty()){
throw new RuntimeException("队列空的,没有数据");
}
return arr[front];
}
/**
* 获取队列个数
* front 在 rear的左边(rear > front)
* 1.队列个数 = rear - front
*
* front 在 rear的右边(rear < front)
* 2.队列个数 = maxSize - front + 0 + rear = rear - front + maxSize
*
* 至于为啥取模?
* 你可以想 咋才能用一个公式表示上述两个公式
* 公式1 算出来差值 大于0的 那么 你+一个数再取这个数的模等于个数组
* 比如 (2 + 3) % 3 = 3
*
*公式二
* 由于rear - front 他是小于0 并且 + 一个数 那么你直接取模 还是这个数字
*
*
* 比如 (-2 + 3)% 3 = 1
* 而 原来 -2 + 3 等于1
* 这个成立条件 前边小于0的这个数 绝对值 小于 后边那个正数的
* 当前问题 前边数字负数的绝对值一定小于数组容量
*
* 所以 用一个公式包含1和2 就是 (rear - front + maxSize)%maxSize
* @return
*/
public int getSize(){
return (rear - front + maxSize)%maxSize;
}
}
class QueueTest(){
@Test
public void testCircleArrayQueue(){
CircleArrayQueue queue = new CircleArrayQueue(3);
queue.addQueue(1);
queue.addQueue(2);
//注意这时候数组还有1个空位置,但是这时候我们约定数组已经满了
int queueQueue = queue.getQueue();
System.out.println("获取1个元素 " + queueQueue);
//把3插入下表2数组中 数组0空
queue.addQueue(3);
queue.show();
}
}
总结
这是我自己一些看法
内容参考尚硅谷韩老师数据结构与算法
代码注释中参考大话数据结构p115