一、思路

1.在此,对front变量的含义进行调整:front就指向队列的第一个元素,也就是说arr[front]就是队列的第一个元素front的初始值 = 0

2.在此,对rear变量的含义进行调整:rear指向队列的最后一个元素的后一个位置,因为希望空出一个空间作为约定,rear的初始值 = 0

3.当队列满时,条件是(rear+1)% maxSize = front【满】

4.队列为空的条件——rear == front

5.基于上述条件,队列中有效的数据个数: (rear+maxSize-front)% maxSize

举例:

6.主要是根据上面的公式来得到环形数列

二、代码实现

import java.util.Scanner;

public class CircleArrayQueueDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("测试数组模拟环形队列的案例");
		CircleArray queue = new CircleArray(4); //这里设计为4,则此时最大的可用空间为3
		char key = ' '; //接受用户输入
		Scanner  sc = 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 = sc.next().charAt(0);  //接受一个字符
			switch(key) {
			case 's':
				queue.showQueue();
				break;
			case 'a':
				System.out.println("输出一个数");
				int value = sc.nextInt();
				queue.addQueue(value);
				break;
			case 'g': //取出数据
				try {
					int res = queue.getQueue();
					System.out.printf("取出的数据是%d\n",res);  //如果队列为空,getQueue抛出异常,这条语句不会输出,执行catch语句
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println(e.getMessage());  // 者的getMessage 指的是下面我们自己写的  getQueue()方法里的 抛出异常时的信息
				}
				break;
			case 'h': //查看队列头的数据
				try {
					int res = queue.headQueue();
					System.out.printf("队列头的数据是%d\n",res);
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println(e.getMessage());
				}
				break;
			case 'e': //退出
				sc.close();
				loop = false;
				break;
			default:
				break;			
			}
						
		}
		System.out.println("程序退出");
	}
}

	class CircleArray{
		private int maxSize;  //表示数组最大容量
		private int front;   //front变量的含义进行调整:
		//front就指向队列的第一个元素,
		//也就是说arr[front]就是队列的第一个元素front的初始值 = 0
		private int rear;     //rear指向队列的最后一个元素的后一个位置,
		//因为希望空出一个空间作为约定,rear的初始值 = 0
		private int[] arr;    //该数据用于存放数据,模拟队列
		
		//构造器
		public CircleArray(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=(rear+1)%maxSize;
		}
		
		//获取队列的数据,出队列
		public int getQueue() {
			//判断队列是否为空
			if(isEmpty()) {
				//通过抛出异常
				throw new RuntimeException("队为空,不能取数据");
			}
			//此处需要知道front是指向队列的第一个元素
			//1.先把front 对应的值保留到一个临时变量
			//2.将front后移   !!!!考虑取模
			//3.将临时保存的变量返回
			int value = arr[front];
			front =(front +1)%maxSize;
			return value;
			
		}
		//显示队列的所有数据
		public void showQueue() {
			//遍历
			if(isEmpty()) {
				System.out.println("队列空的没有数据");
				return;
			}
			//思路:
			//从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];  //因为front指向队列的第一个位置
		}
		
	}