队列
特点:先进先出
举例:银行排号,医院面诊
队列介绍:队列是一个有序列表,可以用数组,链表实现,遵循先进先出原则,即:现存进的要后取出
示意图:
理解:对象Queue拥有两个指针rear(队列尾部)和front(队列首部),初始化均为-1,当添加数据时rear增加front不变,当取数据时rear不变front减少,即取数据在对队首取,加数据在队未加入。
使用数组模拟队列
-
队列本身是有序列表,若使用数组结构来存储队列数据,则队列数组的声明如上图,其中maxsize为该队列的最大容量。
-
上图模拟的就是用数组模拟队列。
代码实现:
import java.util.Scanner; public class Queue { public static void main(String args[]){ ArryQueue arryQueue = new ArryQueue(3); char key=' '; Scanner scanner = new Scanner(System.in); boolean loob=true; //创建一个菜单 while (loob){ System.out.println("s(show):显示队列"); System.out.println("e(exit):退出程序"); System.out.println("a(add):添加数据"); System.out.println("o(out):取出数据"); System.out.println("h(head):查看头数据"); key=scanner.next().charAt(0);//接收一个字符 switch (key){ case 's': arryQueue.showQueue(); break; case 'e': loob=false; break; case 'a': System.out.println("请输入要加入的数据:"); int n=scanner.nextInt(); arryQueue.addQueue(n); break; case 'o': System.out.println(arryQueue.outQueue()); break; case 'h': System.out.println(arryQueue.headQueue()); break; } } } } //使用数组模拟队列 class ArryQueue{ int maxSize;//队列最大容量 int front;//队列头 int rear;//队列未 int[] arr;//模拟队列 //创建队列的构造器 public ArryQueue(int maxSize){ this.maxSize=maxSize; this.arr=new int[maxSize]; this.front=-1;//指向队列头部,指向头部的前一个位置 this.rear=-1;//指向队列未,指向队列未就是最后一个数字 } public boolean isFill(){//判断是否满 return rear==maxSize-1; } public boolean isEmpty(){//判断是否是空 return rear==front; } public void addQueue(int n){//加数据 if (isFill()){ System.out.println("队列满,不可加入"); return; } rear++; arr[rear]=n; } public int outQueue(){//取数据 if (isEmpty()){ //通过抛出异常处理 throw new RuntimeException("对不起队列为空,无法取出"); } front++; return arr[front]; } public void showQueue(){//显示队列的所有数据 if (isEmpty()){ System.out.println("队列为空"); return; } for (int a:arr){ System.out.printf("%d\t",a); System.out.println(); } } public int headQueue(){//显示头部数据,不是取数据 if (isEmpty()){ throw new RuntimeException("队列为空"); } return arr[front+1]; } }
但是上述方法对于数组而言是“一次性的”,下面为数组模拟的环形队列
环形队列
通过取模的方式进行实现
分析:
-
front的含义做出调整使其表示队列的第一个元素,rear表示最后一个元素的后一个元素,希望空出一个空间作为约定(思路有很多)
-
尾索引的下一个为头索引时表示队列满,即队列容量空出一个作为约定,这个在做判断队列满的时候需要注意(rear+1)%maxSize==font 满 (注意这种算法,在rear这个位置是空的,不然没办法判断满,rear与front初始值都为零)
-
rear==font 空
-
数组长度是maxSize实际的有效长度是maxsize-1
-
队列中有效数字的个数(rear+maxSize-front)%maxSize
import java.util.Scanner; public class circleArry { public static void main(String args[]){ cilcleArryQueue arryQueue = new cilcleArryQueue(3); char key=' '; Scanner scanner = new Scanner(System.in); boolean loob=true; //创建一个菜单 while (loob){ System.out.println("s(show):显示队列"); System.out.println("e(exit):退出程序"); System.out.println("a(add):添加数据"); System.out.println("o(out):取出数据"); System.out.println("h(head):查看头数据"); key=scanner.next().charAt(0);//接收一个字符 switch (key){ case 's': arryQueue.showQueue(); break; case 'e': loob=false; break; case 'a': System.out.println("请输入要加入的数据:"); int n=scanner.nextInt(); arryQueue.addQueue(n); break; case 'o': System.out.println(arryQueue.outQueue()); break; case 'h': System.out.println(arryQueue.headQueue()); break; } } } } class cilcleArryQueue{ int maxSize;//队列最大容量 int front;//队列头 int rear;//队列未 int[] arr;//模拟队列 //创建队列的构造器 public cilcleArryQueue(int maxSize){ this.maxSize=maxSize; this.arr=new int[maxSize]; this.front=0;//指向队列头部,指向头部的前一个位置 this.rear=0;//指向队列未,指向队列未就是最后一个数字 } public boolean isFill(){//判断是否满 return (rear+1)%maxSize==front; } public boolean isEmpty(){//判断是否是空 return rear==front; } public void addQueue(int n){//加数据 if (isFill()){ System.out.println("队列满,不可加入"); return; } arr[rear]=n; rear=(rear+1)%maxSize;//rear本身指向最后一个数的后一个数,并且为了防止数组越界取余。 } public int outQueue(){//取数据 if (isEmpty()){ //通过抛出异常处理 throw new RuntimeException("对不起队列为空,无法取出"); } // 将数据临时保存在变量中,将front后移(考虑取模),将临时变量返回。 int temp=arr[front]; front=(front+1)%maxSize; return temp; } public void showQueue(){//显示队列的所有数据 if (isEmpty()){ System.out.println("队列为空"); return; } //被取的数据实际上还存在,所以不能将他们打印出来 for (int i=front;i<front+(rear+maxSize-front)%maxSize;i++){ System.out.printf("arr[%d]=%d\n",i%maxSize,arr[i%maxSize]); System.out.println(); } } public int headQueue(){//显示头部数据,不是取数据 if (isEmpty()){ throw new RuntimeException("队列为空"); } return arr[front]; } }
理解最简单的方法是跟着代码流程画一遍图