分析:
➢对数组模拟队列问题分析并优化:
1)目前数组使用一次就不能用, 没有达到复用的效果
2)将这个数组使用算法,改进成一个环形的数组取模:%
实现:
定义队列类
private int maxSize;//数组的最大容量 private int front;//头结点,初始值为0,指向队列的第一个元素 private int read;//尾结点,初始值为0,指向元素的最后一个元素的后一个位置 private int[] arr;//创建数组用于存放数据,模拟队列
初始化队列
/** * 构造方法 * @param arrMaxSize 队列能够拥有的最大容量 */ public CircularQueue(int arrMaxSize){ maxSize = arrMaxSize;//传入数据表示队列能够拥有的最大容量 arr = new int[maxSize];//初始化数组 front = 0;//指向队列头结点 read = 0;//指向的是队列的尾结点 }
队满
/** * 判断队列是否满了,判断队列是否满的条件是:(read+1)%maxSize == front * @return */ public boolean isFull(){ return (read+1)%maxSize == front; }
队空
/** * 判断队列是否为空 * @return */ public boolean isAir(){ return front == read; }
添加数据
/** * 添加数据到队列 * @param data:添加的数据 */ public void add(int data){ //先判断队列是否满 if (isFull()){ System.out.println("队列已满,不能加入数据!"); return; } //直接将数据加入 arr[read] = data; read = (read+1) % maxSize; }
出队列
/** * 获取队列的数据,出队列 * @return */ public int get(){ //先判断队列是否为空 if (isAir()){ //通过抛出异常来解决 throw new RuntimeException("队列空,不能取数据!"); } /** * //这里需要分析出front是指向队列的第一个元素 * // 1.先把front对应的值保留到一个临时变量 * // 2.将front后移,考虑取模,如果直接++回报下标越界异常 * // 3.将临时保存的变量返回 */ int value = arr[front]; front = (front + 1)%maxSize; return value; }
获取当前队列有效个数
/** * 求出当前队列有效数据的个数 */ public int size(){ return (read+maxSize-front)%maxSize; }
打印队列
/** * 打印数据,就是遍历arr数组 */ public void listQueue(){ //判断队列是否为空 if (isAir()){ System.out.println("队列为空,没有数据!"); } //从front开始遍历,遍历多少个元素 for (int i=front;i<front+size();i++){ System.out.println("arr["+i%maxSize+"]="+arr[i%maxSize]); } }
显示队头
/** * 显示队列的头数据 */ public int headQueue(){ if (isAir()){ throw new RuntimeException("队列是空的没有数据"); } return arr[front]; }
完整代码:
import java.util.Scanner; //Circular queue public class Test03_数组模拟环形队列 { public static void main(String[] args) { CircularQueue queue = new CircularQueue(4);//最多只能存储三个有效数据,因为设置的是有一个预留的空间 char value = ' '; Scanner s = new Scanner(System.in); boolean loop = true; while (loop){ System.out.println("=================================="); 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):查看队列头的数据"); System.out.println("=================================="); //接受用户输入的一个字符 System.out.print("请输入指令:"); value = s.next().charAt(0); switch (value){ case 's'://显示队列 queue.listQueue(); break; case 'g'://取数据 System.out.println("取出的数据是:"+queue.get()); break; case 'a'://添加数据 System.out.print("请输入一个数:"); int index = s.nextInt(); queue.add(index); break; case 'h'://查看队列头 System.out.println("队列的头是:"+queue.headQueue()); break; case 'e'://退出程序 loop = false; break; default: System.out.println("您好,您输入的字符不合法,请重新输入!"); break; } } System.out.println("您已经成功退出!"); } } class CircularQueue{ private int maxSize;//数组的最大容量 private int front;//头结点,初始值为0,指向队列的第一个元素 private int read;//尾结点,初始值为0,指向元素的最后一个元素的后一个位置 private int[] arr;//创建数组用于存放数据,模拟队列 /** * 构造方法 * @param arrMaxSize 队列能够拥有的最大容量 */ public CircularQueue(int arrMaxSize){ maxSize = arrMaxSize;//传入数据表示队列能够拥有的最大容量 arr = new int[maxSize];//初始化数组 front = 0;//指向队列头结点 read = 0;//指向的是队列的尾结点 } /** * 判断队列是否满了,判断队列是否满的条件是:(read+1)%maxSize == front * @return */ public boolean isFull(){ return (read+1)%maxSize == front; } /** * 判断队列是否为空 * @return */ public boolean isAir(){ return front == read; } /** * 添加数据到队列 * @param data:添加的数据 */ public void add(int data){ //先判断队列是否满 if (isFull()){ System.out.println("队列已满,不能加入数据!"); return; } //直接将数据加入 arr[read] = data; read = (read+1) % maxSize; } /** * 获取队列的数据,出队列 * @return */ public int get(){ //先判断队列是否为空 if (isAir()){ //通过抛出异常来解决 throw new RuntimeException("队列空,不能取数据!"); } /** * //这里需要分析出front是指向队列的第一个元素 * // 1.先把front对应的值保留到一个临时变量 * // 2.将front后移,考虑取模,如果直接++回报下标越界异常 * // 3.将临时保存的变量返回 */ int value = arr[front]; front = (front + 1)%maxSize; return value; } /** * 求出当前队列有效数据的个数 */ public int size(){ return (read+maxSize-front)%maxSize; } /** * 打印数据,就是遍历arr数组 */ public void listQueue(){ //判断队列是否为空 if (isAir()){ System.out.println("队列为空,没有数据!"); } //从front开始遍历,遍历多少个元素 for (int i=front;i<front+size();i++){ System.out.println("arr["+i%maxSize+"]="+arr[i%maxSize]); } } /** * 显示队列的头数据 */ public int headQueue(){ if (isAir()){ throw new RuntimeException("队列是空的没有数据"); } return arr[front]; } }