队列
队列应用场景:银行排队叫号
队列是一个有序列表,可以用数组或是链表实现
遵循先入先出原则。即:先存入队列的数据,要先取出,后存入的要后取出
数组模拟队列:
用数组的结构来存储队列,其中maxSize是该队列的最大容量。
因为队列的输出、输入是分别从前后端来处理,因此需要两个变量front及rear分别记录队列前后端的下标,front会随着数据输出而改变,而rear则是随着数据输入而改变
将数据存入队列称为“addQueue”,addQueue的处理需要有两个步骤:
1)将尾指针往后移:rear+1,当front==rear 【空】
2)若尾指针rear小于队列的最大下标maxSize-1,则将数据存入rear所指的数组元素中,
否则无法存入数据。rear==maxSize-1 【队列满】
1 import java.util.Scanner; 2 3 public class ArrayQueueDemo { 4 5 public static void main(String[] args) { 6 //测试 7 //创建一个队列 8 ArrayQueue queue = new ArrayQueue(3); 9 char key = ' ';//接收用户输入 10 Scanner scanner = new Scanner(System.in); 11 boolean loop = true; 12 13 //输出一个菜单 14 while(loop){ 15 System.out.println("s(show):显示队列"); 16 System.out.println("e(exit):退出程序"); 17 System.out.println("a(add):添加数据到队列"); 18 System.out.println("g(get):从队列取出数据"); 19 System.out.println("h(show):查看队列的头数据"); 20 key = scanner.next().charAt(0);//接收一个字符 21 switch(key){ 22 case 's': 23 queue.showQueue(); 24 break; 25 case 'a': 26 System.out.println("输出一个数"); 27 int value = scanner.nextInt(); 28 queue.addQueue(value); 29 break; 30 case 'g': 31 try{ 32 int res = queue.getQueue(); 33 System.out.printf("取出的数据是%d\n",res); 34 }catch (Exception e){ 35 System.out.println(e.getMessage()); 36 } 37 break; 38 case 'h'://查看队列的头数据 39 try{ 40 int res = queue.headQueue(); 41 System.out.printf("队列的头数据是%d\n",res); 42 }catch (Exception e){ 43 System.out.println(e.getMessage()); 44 } 45 break; 46 case 'e'://退出 47 scanner.close(); 48 loop = false; 49 break; 50 default: 51 break; 52 } 53 } 54 System.out.println("程序退出"); 55 } 56 } 57 58 //使用数组模拟队列-写一个ArrayQueue类 59 class ArrayQueue{ 60 private int maxSize;//表示数组的最大容量 61 private int front;//队列头 62 private int rear; //队列尾 63 private int[] arr; //该数据用于存放数据,模拟队列 64 65 //创建队列的构造器 66 public ArrayQueue(int arrMaxSize){ 67 maxSize = arrMaxSize; 68 arr = new int[maxSize]; 69 front = -1; //指向队列头部,front是指向队列头的前一个位置 70 rear = -1; //指向队列尾,直接指向队列尾部(包含)就是队列最后一个数据 71 } 72 //判断队列是否满 73 public boolean isFull(){ 74 return rear == maxSize -1; 75 } 76 77 //判断队列是否为空 78 public boolean isEmpty(){ 79 return rear == front; 80 } 81 //添加数据到队列 82 public void addQueue(int n){ 83 //判断队列是否满 84 if (isFull()){ 85 System.out.println("队列满,不能加入数据"); 86 87 } 88 rear++;//让rear后移 89 arr[rear]=n; 90 //上面俩个可以合并成 arr[++rear] = n 91 92 } 93 94 //获取队列的数据,出队列 95 public int getQueue(){ 96 //判断队列是否空 97 if (isEmpty()){ 98 //通过抛出异常处理 99 throw new RuntimeException("队列空,不能取数据"); 100 101 } 102 front++;//front后移 103 return arr[front]; 104 } 105 106 //显示队列的所有数据 107 public void showQueue(){ 108 //遍历 109 if (isEmpty()){ 110 System.out.println("队列空的,没有数据"); 111 return; 112 } 113 for (int i = 0; i <arr.length ; i++) { 114 System.out.printf("arr[%d]=%d\n",i,arr[i]); 115 } 116 } 117 118 //显示队列的头数据,注意不是取出数据 119 public int headQueue(){ 120 //判断 121 if (isEmpty()){ 122 123 throw new RuntimeException("队列空的,没有数据"); 124 } 125 return arr[front+1]; 126 } 127 }
问题分析:优化
1)目前数组使用一次就不能用,没有达到复用
2)使用算法改成一个环形队列 取模: %

浙公网安备 33010602011771号