赞
踩
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方法把队列里面的数据全部出队以后,在往队列里面加入数据的时候,会发现队列已经满了
所以目前还有两个问题:
目前数组使用一次就不能再次使用,没有达到复用的效果。
我们要将这个数组使用算法,改进称为一个环形队列,取模: %
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。