网站首页域名如何设置访问快/最彻底的手机优化软件
一、队列介绍
1、队列是一个有序列表,可以用数组或者链表实现。
2、遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出。
3、示意图:
数组模拟队列
1、队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图, 其中 maxSize 是该队列的最大容量。
2、因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front及 rear分别记录队列前后端的下标,front 会随着数据输出而改变,而 rear则是随着数据输入而改变,如图所示:
思路:
当我们将数据存入队列时称为“addQueue”,addQueue的处理步骤需要两个:
1)将尾指针往后移:rear+1 , 当front == rear [空]
2)若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear所指的数组元素中,否则无法存入数据。 rear == maxSize - 1[队列满]
代码实现
package com.structure.queue;import java.util.Scanner;/*** @PackgeName: com.structure.queue* @ClassName: Queue* @Author: Hercules* Date: 2020/9/7 18:30* project name: dataStructure* @Version:* @Description:用数组模拟队列*/
public class ArrayQueueDemo {public static void main(String[] args) {//测试//创建一个队列ArrayQueue arrayQueue = new ArrayQueue(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(exit):查看头部的数据");//接收一个字符key = scanner.next().charAt(0);switch (key) {case 's':arrayQueue.showQueue();break;case 'a':System.out.println("输入一个数");int value = scanner.nextInt();arrayQueue.addQueue(value);break;case 'g':try {int res = arrayQueue.getQueue();System.out.printf("取出的数据是%d\n", res);} catch (Exception e) {System.out.println(e.getMessage());}break;case 'h':try {int res = arrayQueue.headQueue();System.out.printf("队列头的数据是%d\n", res);} catch (Exception e) {System.out.println(e.getMessage());}break;case 'e':scanner.close();loop = false;break;default:break;}}System.out.println("程序退出");}
}/*** 使用数组模拟队列*/
class ArrayQueue {/*** 表示数组的最大容量*/private int maxSize;/*** 表示队列头*/private int front;/*** 表示队列尾*/private int rear;/*** 用于存放数据,模拟队列*/private int[] arr;/*** 数组模拟队列的构造函数** @param arrMaxSize*/public ArrayQueue(int arrMaxSize) {maxSize = arrMaxSize;arr = new int[maxSize];//指向队列头部,分析出front是指向队列头的前一个位置front = -1;//指向队列尾部,指向队列尾部的数据(就是队列的最后一个位置)rear = -1;}/*** 判断队列是否满** @return*/public boolean isFull() {return rear == maxSize - 1;}/*** 判断队列是否为空** @return*/public boolean isEmpty() {return rear == front;}/*** 添加数据到队列** @param n*/public void addQueue(int n) {//判断队列是否满了if (isFull()) {System.out.println("队列满,不能加入数据~");return;}rear++;//让rear后移arr[rear] = n;}/*** 获取队列的数据,出队列** @return*/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]);}}/*** 显示队列头的数据,注意不是取出数据** @return*/public int headQueue() {//判断if (isEmpty()) {throw new RuntimeException("队列空的,没有数据");}//上面的代码已经提到了front指向队列头的前一个位置return arr[front + 1];}
}
具体运行的结果大家可以粘贴到IDE上面去跑我这里就不粘贴结果了,乍一看可能所有的操作都是正确的,但是其实这么实现是存在缺陷的,那就是当你用get方法把队列里面的数据全部出队以后,在往队列里面加入数据的时候,会发现队列已经满了
所以目前还有两个问题:
问题
目前数组使用一次就不能再次使用,没有达到复用的效果。
我们要将这个数组使用算法,改进称为一个环形队列,取模: %