20210329-算法学习-队列
1.队列使用场景(银行排队案例):
图1.1
1.1.队列介绍:
队列是一种特殊的现行列表,他只允许在表的前端(front)进行删除操作,而表的后端(rear)进行插入操作。
当进行插入操作的端称为队尾,进行删除操作的端称为队头,当队列中没有元素时,称为空队列。
在队列这种数据结构中个,最先插入的元素将是最先被删除的元素,反之最后插入的元素将是最后被删除的元素,因此队列又称为 "先进先出" (FIFO-first in first out) 的线性表。
队列空的条件:front=rear
队列满的条件:rear=MAXSIZE
1.2.队列的链表实现:
在队列的形成过程中,可以利用线性链表的原理,来生成一个队列。
基于链表的队列,要动态创建和删除节点,效率较低,但是可以动态增长。
队列采用的FIFO(first in first out),新元素(等待进入队列的元素) 总是被插入到链表的尾部,而读取的时候总是从链表的头部开始读取,每次读取一个元素,释放一个元素。
所谓动态创建,动态释放,因而也不存在溢出等问题,由于链表由结构体间接而成,遍历也方便
1.3.队列的数组实现:
队列本身就是有序列表,若要使用数组的结构来存储队列的数据,则队列数组的声明如下(图1.2),其中 maxSize是该队列的最大容量。
因为队列的输出,输入的是分别从前后端来处理的,因此需要两个变量 front和rear 分别记录队列前后的下标,front 会随着数据输出而改变,而rear 则是随着数据输入而改变的
图1.2
1.4.数组模拟队列的基本思想:
当数组表示队列的时候,该数组只能被使用一次
队列是一个有序列表,可以用数组或链表表示
遵循先入先出的原则,即先存入队列中的数据,要先取出,后存入的数据后取出
定义队列的时候,主要有三个参数(front头,rear尾,maxSize),maxSize即为队列的最大容量
判断队列是不是空,根据 rear==front true的话 则这个队列为空
判断该队列是不是已经存满数据 rear==arr[maxSize-1] true的话 则表明这个队列已经满了
当给该队列添加数据的时候,需要rear++ front不变
当从该队列中取出数据的时候,则需要 front++ rear不变
2.代码:
package com.atAlgorithmTest; /** * @Author: lisongtao * @Date: 2021/3/29 14:43 */ import com.sun.jmx.remote.internal.ArrayQueue; import java.util.Scanner; /** * @ClassName QueryArray * @Description银行排队-队列 * @Author DELL * @Date 2021/03/29 14:43 **/ public class QueueArray { public static void main(String[] args) { //创建一个队列 QueueArrayCreate queueArray = new QueueArrayCreate(3); char key = ' '; Scanner scanner = 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 = scanner.next().charAt(0); switch (key){ case 's': queueArray.showQueue(); break; case 'a': System.out.println("输入一个数"); int i = scanner.nextInt(); queueArray.addQueue(i); break; case 'g': try { int res = queueArray.getQueue(); System.out.println("取出的数据是: "+res); } catch (Exception e) { System.out.println(e.getMessage()); } break; case 'h': try { int res = queueArray.headQueue(); System.out.println("队列头数据是: "+res); } catch (Exception e) { System.out.println(e.getMessage()); } break; case 'e': scanner.close(); loop=false; break; default: break; } } System.out.println("程序退出"); } } class QueueArrayCreate{ private int maxSize;//表示数组的最大容量 private int front;//队列头 private int rear;//队列尾 private int[] arr;//该数组用来存放数据,模拟队列 //创建一个队列构造器 public QueueArrayCreate(int arrMaxSize){ maxSize = arrMaxSize; arr = new int[maxSize]; front = -1;//指向队列头部(队列头的前一个位置) rear = -1;//指向队列尾部(队列的最后一个数据) } //判断队列是否已满 public boolean isFull(){ return rear == maxSize-1; } //需要判断队列是否为空 public boolean isEmpty(){ return rear == front; } //添加数据到队列中 public void addQueue(int n){ //判断队列是否已满 if(isFull()){ System.out.println("队列已满,不能再添加数据"); return; } rear++;//队列后移 arr[rear] = n; } //获取队列的数据,出队列 public int getQueue(){ if (isEmpty()){ //当队列为空时,取不出数据 throw new RuntimeException("队列为空,不能取出数据"); } front++;//front后移 return arr[front]; } //显示队列 public void showQueue(){ if (isEmpty()){ System.out.println("队列为空,没有数据"); return; } for (int i = 0; i<arr.length; i++){ System.out.printf("arr[%d]=%d\n",i,arr[i]); } } //显示队列头的数据 public int headQueue(){ if (isEmpty()) { System.out.println("队列为空,没有数据"); } return arr[front+1]; } }