2、队列-数组模拟队列
来源:https://www.bilibili.com/video/BV1B4411H76f?p=9
一、思路
1、队列是一个有序的列表,它遵循先入先出的原则。为了用数组实现一个队列,首先创建一个代表队列的类,类中的属性包括队列的最大容量(maxSize),队列头指针(front,初始值-1),队列尾指针(rear,初始值-1),以及用来存放数据的数组(arr);
2、当向队列中添加数据时,尾指针加一(rear++),之后向数组中尾指针所在的下标加入一个数据;
3、当数据要出队列时,头指针加一(front++),之后取出数组中头指针所在的下标对应的数据;
4、特别要注意的是,这里设置了队列的最大容量,因此只有队列不满时(rear<maxSize-1)才可以向队列添加数据,当队列非空时(rear!=front)数据才能出队列。
二、实现
1、创建一个代表队列的类,并将队列头指针和尾指针初始化为-1。此处默认要添加的数据为int类型
1 //创建一个代表队列的类 2 class ArrayQueue{ 3 private int maxSize;//队列的最大容量 4 private int front;//队列头指针 5 private int rear;//队列尾指针 6 private int[] arr;//存放队列数据 7 8 //构造器,将队列头指针和尾指针初始化为-1 9 public ArrayQueue(int maxSize) { 10 this.maxSize = maxSize; 11 this.front = -1; 12 this.rear = -1; 13 this.arr = new int[maxSize]; 14 } 15 }
2、在ArrayQueue类中增加一个向队列中添加数据的方法。由于只有队列不满时才可以添加,因此还要额外添加一个判断队列满的函数。
1 //判断队列满 2 public boolean isFull(){ 3 if(rear == maxSize - 1){ 4 return true; 5 } 6 return false; 7 } 8 9 //向队列中添加数据 10 public void addData(int data){ 11 if(this.isFull()){ 12 System.out.println("队列已满,不能继续添加数据"); 13 }else { 14 rear++; 15 arr[rear] = data; 16 } 17 }
3、在ArrayQueue类中增加一个展示队列数据的方法,测试一下增加数据的功能。由于只有当队列不为空时才能对数据进行展示,因此需要再添加一个判断队列空的方法。
1 //判断队列空 2 public boolean isEmpty(){ 3 if(front == rear){ 4 return true; 5 } 6 return false; 7 } 8 9 //队列数据展示 10 public void showData(){ 11 if(this.isEmpty()){ 12 System.out.println("队列为空,不能展示数据"); 13 }else { 14 for (int i = 0; i < arr.length; i++) { 15 System.out.printf("arr[%d]=%d ",i,arr[i]); 16 } 17 } 18 }
对增加数据的功能进行测试
1 public static void main(String[] args) { 2 int maxSize = 3; 3 Scanner sc = new Scanner(System.in); 4 ArrayQueue arrayQueue = new ArrayQueue(maxSize); 5 arrayQueue.showData(); 6 while (true){ 7 int value = sc.nextInt(); 8 arrayQueue.addData(value); 9 arrayQueue.showData(); 10 } 11 }
结果
队列为空,不能展示数据 1 arr[0]=1 arr[1]=0 arr[2]=0 2 arr[0]=1 arr[1]=2 arr[2]=0 3 arr[0]=1 arr[1]=2 arr[2]=3 4 队列已满,不能继续添加数据 arr[0]=1 arr[1]=2 arr[2]=3
4、 在ArrayQueue类中增加一个出队列功能。
1 //出队列 2 public int removeData(){ 3 if(this.isEmpty()){ 4 throw new RuntimeException("队列为空,无法移除数据"); 5 }else { 6 front++; 7 return arr[front]; 8 } 9 }
测试,在程序中手动添加了三个数据,依次移除。
1 public static void main(String[] args) { 2 int maxSize = 3; 3 ArrayQueue arrayQueue = new ArrayQueue(maxSize); 4 arrayQueue.addData(1); 5 arrayQueue.addData(2); 6 arrayQueue.addData(3); 7 8 int val = 0; 9 10 val = arrayQueue.removeData(); 11 System.out.println("移除的值为:"+val); 12 arrayQueue.showData(); 13 14 System.out.println(); 15 16 val = arrayQueue.removeData(); 17 System.out.println("移除的值为:"+val); 18 arrayQueue.showData(); 19 20 System.out.println(); 21 22 val = arrayQueue.removeData(); 23 System.out.println("移除的值为:"+val); 24 arrayQueue.showData(); 25 26 System.out.println(); 27 28 val = arrayQueue.removeData(); 29 System.out.println("移除的值为:"+val); 30 arrayQueue.showData(); 31 32 }
结果
移除的值为:1 arr[0]=1 arr[1]=2 arr[2]=3 移除的值为:2 arr[0]=1 arr[1]=2 arr[2]=3 移除的值为:3 队列为空,不能展示数据 Exception in thread "main" java.lang.RuntimeException: 队列为空,无法移除数据 at com.neuzhaoxin.queue.ArrayQueue.removeData(ArrayQueue.java:58) at com.neuzhaoxin.queue.ArrayQueueTest.main(ArrayQueueTest.java:45)
5、虽然数组内的数据未改变,但每次数据出队列后,队列头指针会变化,因此在队列中该数据已经不存在了,尝试输出该头指针。
1 //输出头指针对应的内容 2 public int headPoint(){ 3 if(this.isEmpty()){ 4 throw new RuntimeException("队列为空,无法寻找头指针"); 5 }else { 6 return arr[front + 1]; 7 } 8 }
结果
移除的值为:1 头指针对应的值为:2 arr[0]=1 arr[1]=2 arr[2]=3 移除的值为:2 头指针对应的值为:3 arr[0]=1 arr[1]=2 arr[2]=3 移除的值为:3 Exception in thread "main" java.lang.RuntimeException: 队列为空,无法寻找头指针 at com.neuzhaoxin.queue.ArrayQueue.headPoint(ArrayQueue.java:68) at com.neuzhaoxin.queue.ArrayQueueTest.main(ArrayQueueTest.java:43)
三、问题
这个队列只能用一次,除非程序重新启动,因为队列大小有限制且头指针在删除数据后向后移动,就再也无法回来了。想要解决,可以把这个队列更新成一个环形队列。