队列简介
概念:
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。
特点:
1.队列是一个有序列表,可以用数组或者链表实现
2.遵循先入先出的原则。即:先存入队列的数组,先取出,后存入的数据后取出
数组模拟队列实现
示意图:
实现思路:
1.队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如上图,其中maxSize是该队列的最大容量。
2.因为队列的输入、输出是分别从前后端来处理,因此需要两个变量front以及rear分别记录队列前后端的下标,front会随着数据而改变,而rear则是随着数据输入而改变,如上图所示。
3.当我们将数据存入队列时称为"addQueue",addQueue的处理需要两个步骤:
1.将尾指针后移:rear+1,当front==rear时,此时队列为空。
2.若尾指针rear小于队列的最大的下标maxSize-1,则将数据存入rear所指的数组元素中,否则队列满,无法存入数据。
代码实现:
1 package com.xihua.queue; 2 3 import java.util.Scanner; 4 5 public class ArrayQueueDemo { 6 public static void main(String[] args) { 7 //进行简单的测试 8 //创建一个队列 9 ArrayQueue queue=new ArrayQueue(3); 10 //接受用户输入,注意''之间有空格 11 char key = ' '; 12 //键盘输入 13 Scanner scanner=new Scanner(System.in); 14 //声明一个boolean类型的loop,控制循环 15 boolean loop=true; 16 //简单输出一个菜单便于提示操作 17 while (loop){ 18 System.out.println("s(show): 显示队列"); 19 System.out.println("e(exit): 退出程序"); 20 System.out.println("a(add): 添加数据到队列"); 21 System.out.println("g(get): 从队列取出数据"); 22 System.out.println("h(head): 查看队列头的数据"); 23 //接受一个字符 24 key=scanner.next().charAt(0); 25 switch (key){ 26 case 's': 27 queue.showQueue(); 28 break; 29 case 'a': 30 System.out.println("输入一个数"); 31 int value=scanner.nextInt(); 32 queue.addQueue(value); 33 break; 34 case 'g': 35 try { 36 int res = queue.getQueue(); 37 System.out.println("取出的数据是:"+ res); 38 } catch (Exception e) { 39 // TODO: handle exception 40 System.out.println(e.getMessage()); 41 } 42 break; 43 case 'h': //查看队列头的数据 44 try { 45 int res = queue.headQueue(); 46 System.out.println("队列头的数据是:"+res); 47 } catch (Exception e) { 48 // TODO: handle exception 49 System.out.println(e.getMessage()); 50 } 51 break; 52 case 'e': //退出 53 scanner.close(); 54 loop = false; 55 break; 56 default: 57 break; 58 } 59 } 60 System.out.println("程序退出~~"); 61 } 62 } 63 class ArrayQueue{ 64 //表示数组的最大容量 65 private int maxSize; 66 //队列头 67 private int front; 68 //队列尾 69 private int rear; 70 //该数组用于存放数据,模拟队列 71 private int[] arr; 72 //创建队列的构造器,传递最大容量的值 73 public ArrayQueue(int arrMaxSiza){ 74 maxSize=arrMaxSiza; 75 arr=new int[maxSize]; 76 //指向队列头部,分析出front是指向队列头的前一个位置. 77 front=-1; 78 //指向队列尾部,指向队列尾的数据(即就是队列最后一个数据) 79 rear=-1; 80 } 81 //判断队列是否已满 82 public boolean isFull(){ 83 //当队列尾部与maxSize-1相等时,说明队列已满 84 return rear==maxSize-1; 85 } 86 //判断队列是否为空 87 public boolean isEmpty(){ 88 //当队列头与队列尾相等时,说明队列中没有数据 89 return rear==front; 90 } 91 //添加数据到队列中 92 public void addQueue(int n){ 93 //判断队列是否已满 94 if(isFull()){ 95 System.out.println("队列已满,不能加入数据!!!"); 96 } 97 //尾指针后移 98 rear++; 99 arr[rear]=n; 100 } 101 //获取队列的数据,出队列 102 public int getQueue(){ 103 //判断队列是否为空 104 if(isEmpty()){ 105 //抛出自定义异常 106 throw new RuntimeException("队列为空,没有数据可取!!!"); 107 } 108 //头指针后移 109 front++; 110 return arr[front]; 111 } 112 //显示队列所有数据 113 public void showQueue(){ 114 //判断队列是否为空 115 if(isEmpty()){ 116 //抛出自定义异常,这里可以写成System.out.println()提示队列为空就行 117 throw new RuntimeException("队列为空,没有数据可取!!!"); 118 } 119 for(int i=0;i<arr.length;i++){ 120 //System.out.println(arr[i]); 121 System.out.printf("arr[%d]=%d ", i, arr[i]); 122 } 123 } 124 //显示队列头数据,注意不是去出数据 125 public int headQueue(){ 126 //判断队列是否为空 127 if(isEmpty()){ 128 //抛出自定义异常 129 throw new RuntimeException("队列为空,没有数据可取!!!"); 130 } 131 //注意front初始值为-1 132 return arr[front+1]; 133 } 134 135 }
运行结果:在测试的过程中,注意要先添加数据到队列中,再进行测试,不然会直接抛出我们自己定义的异常:Exception in thread "main" java.lang.RuntimeException: 队列为空,没有数据可取!!!