队列1

1、队列的一个使用场景

银行排队的案例:
在这里插入图片描述

2、队列介绍

  1. 队列是一个 有序列表,可以用 数组或是 链表来实现。
  2. 遵循 先入先出的原则。即: 先存入队列的数据,要先取出。后存入的要后取出
  3. 示意图:(使用数组模拟队列示意图)
    在这里插入图片描述

3、数组模拟队列思路

  • 队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图, 其中 maxSize 是该队 列的最大容量。
  • 因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front 及 rear 分别记录队列前后端的下标, front
    会随着数据输出而改变,而 rear 则是随着数据输入而改变,如图所示:
    在这里插入图片描述
    当我们将数据存入队列时称为”addQueue”,addQueue 的处理需要有两个步骤:思路分析
  1. 将尾指针往后移:rear+1 , 当 front == rear 【空】
  2. 若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear 所指的数组元素中,否则无法存入数据。
    rear == maxSize - 1[队列满]

代码实现

ArrayQueue.java

package com.yg.datastructures.queue;

/**
 * @Description: 数组 模拟 队列 模型
 * @Author yg
 * @Date 2021-03-20 10:33
 */
public class ArrayQueue {
    private final int maxSize;
    /**
     * 该数组存放数据,模拟队列
     */
    private final String[] arr;
    /**
     * 队列头 指针
     */
    private final int front;
    /**
     * 队列尾部 指针
     */
    private int rear;

    /**
     * 串讲队列 构造器
     */
    public ArrayQueue(int arrMaxSize) {
        maxSize = arrMaxSize;
        arr = new String[maxSize];
        /**
         * 指向队列头部,
         * 指向队列头部的前一个位置。
         *
         */
        front = -1;
        /**
         * 指向队列尾
         * 指向队列尾的数据,指向队列的最后一个数据
         */
        rear = -1;
    }


    /**
     * 判断队列是否满了
     *
     * @return
     */
    public boolean isFull() {
        return rear == maxSize - 1;
    }


    /**
     * 判断队列是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        return rear == front;
    }

    /**
     * 添加数据到队列
     */
    public void addQueue(String data) {
        if (isFull()) {
            System.out.println("队列已经满了,不能加入数据");
            return;
        }
        arr[++rear] = data;
    }

    /**
     * 获取队列的一个元素
     *
     * @return String 数据
     */
    public String getQueue() {
        if (isEmpty()) {
            System.out.println("队列已经没有数据了,对不起");
            throw new RuntimeException("队列已经没有数据了,不能获取数据");
        }
        //front 指向的是队列头的钱一个位置
        return arr[++front];
    }

    /**
     * 显示队列的所有数据
     */
    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列为空,没有数据!");
            return;
        }
        System.out.println("-------------------开始打印队列-------------------");
        for (String data : arr) {
            System.out.println(data);
        }
        System.out.println("-------------------结束打印队列-------------------");

    }

    /**
     * 显示队列的头部数据
     */
    public void showHeadQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空,没有头部数据显示!");
        }
        System.out.println("队列的头部元素是:" + arr[front + 1]);
    }
}

ArrayQueueTest.java

package com.yg.datastructures.queue;

import java.util.Scanner;

/**
 * @Description: 使用数组模拟队列
 * @Author yg
 * @Date 2021-03-20 10:31
 */
public class ArrayQueueTest {
    public static void main(String[] args) {
        System.out.println("----------------程序开始----------------------");

        ArrayQueue arrayQueue = new ArrayQueue(5);
//        arrayQueue.addQueue("yg");
//        arrayQueue.addQueue("fm");
//        arrayQueue.addQueue("lb");
//        arrayQueue.addQueue("was");
//        arrayQueue.addQueue("bjy");
//        arrayQueue.showQueue();
//        arrayQueue.showHeadQueue();
//        String queue = arrayQueue.getQueue();
//        System.out.println("获取到队列的一个元素 = " + queue);
//        arrayQueue.showQueue();
//        arrayQueue.showHeadQueue();
//
        Scanner scanner = new Scanner(System.in);
        boolean loop = true;
        while (loop) {
            System.out.println("---------------控制台----------------");
            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) : 展示队列头部元素");
            System.out.println("---------------控制台----------------");

            String input = scanner.next();

            switch (input) {
                case "s":
                    arrayQueue.showQueue();
                    break;
                case "e":
                    scanner.close();
                    loop = false;
                    break;
                case "a":
                    System.out.println("请输入添加的元素:");
                    String next = scanner.next();
                    arrayQueue.addQueue(next);
                    break;
                case "h":
                    try {
                        arrayQueue.showHeadQueue();
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case "g":
                    try {
                        String queue = arrayQueue.getQueue();
                        System.out.println("头部元素 =" + queue);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                default:
                    break;
            }
        }
        System.out.println("----------------程序结束----------------------");
    }
}


问题分析并优化

  1. 目前数组使用一次就不能用, 没有达到复用的效果
  2. 将这个数组使用算法,改进成一个列 环形的队列 取模:%

解决方法1:
改造获取头部元素的方法,当获取了一个元素之后,将其他元素统一向前移动。

 /**
     * 获取队列的一个元素
     *
     * @return String 数据
     */
    public String getQueue() {
        if (isEmpty()) {
            System.out.println("队列已经没有数据了,对不起");
            throw new RuntimeException("队列已经没有数据了,不能获取数据");
        }
        //front 指向的是队列头的钱一个位置
        //front++;
        String head = arr[front + 1];
        //这里删除第一个元素,并把其他的元素向前移动 ,front 不需要移动。
        for (int i = 0; i < arr.length - 1; i++) {
            arr[i] = arr[i + 1];
        }
        //尾部指针 -1
        rear--;
        return head;
    }

该方法满足数组的重复利用,但是存在一个效率问题,当队列特别大的时候,需要统一遍历一遍队列并移动,并且每次获取一个元素的时候都需要该遍历移动。

改造后运行结果:

D:\jdk1.8.0_251\bin\java.exe -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:14148,suspend=y,server=n -javaagent:C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2020.3\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "D:\jdk1.8.0_251\jre\lib\charsets.jar;D:\jdk1.8.0_251\jre\lib\deploy.jar;D:\jdk1.8.0_251\jre\lib\ext\access-bridge-64.jar;D:\jdk1.8.0_251\jre\lib\ext\cldrdata.jar;D:\jdk1.8.0_251\jre\lib\ext\dnsns.jar;D:\jdk1.8.0_251\jre\lib\ext\jaccess.jar;D:\jdk1.8.0_251\jre\lib\ext\jfxrt.jar;D:\jdk1.8.0_251\jre\lib\ext\localedata.jar;D:\jdk1.8.0_251\jre\lib\ext\nashorn.jar;D:\jdk1.8.0_251\jre\lib\ext\sunec.jar;D:\jdk1.8.0_251\jre\lib\ext\sunjce_provider.jar;D:\jdk1.8.0_251\jre\lib\ext\sunmscapi.jar;D:\jdk1.8.0_251\jre\lib\ext\sunpkcs11.jar;D:\jdk1.8.0_251\jre\lib\ext\zipfs.jar;D:\jdk1.8.0_251\jre\lib\javaws.jar;D:\jdk1.8.0_251\jre\lib\jce.jar;D:\jdk1.8.0_251\jre\lib\jfr.jar;D:\jdk1.8.0_251\jre\lib\jfxswt.jar;D:\jdk1.8.0_251\jre\lib\jsse.jar;D:\jdk1.8.0_251\jre\lib\management-agent.jar;D:\jdk1.8.0_251\jre\lib\plugin.jar;D:\jdk1.8.0_251\jre\lib\resources.jar;D:\jdk1.8.0_251\jre\lib\rt.jar;D:\IdeaProjects\datastructures\target\classes;D:\RepMaven\org\springframework\boot\spring-boot-starter-web\2.4.4\spring-boot-starter-web-2.4.4.jar;D:\RepMaven\org\springframework\boot\spring-boot-starter\2.4.4\spring-boot-starter-2.4.4.jar;D:\RepMaven\org\springframework\boot\spring-boot\2.4.4\spring-boot-2.4.4.jar;D:\RepMaven\org\springframework\boot\spring-boot-autoconfigure\2.4.4\spring-boot-autoconfigure-2.4.4.jar;D:\RepMaven\org\springframework\boot\spring-boot-starter-logging\2.4.4\spring-boot-starter-logging-2.4.4.jar;D:\RepMaven\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;D:\RepMaven\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;D:\RepMaven\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;D:\RepMaven\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;D:\RepMaven\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;D:\RepMaven\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\RepMaven\org\yaml\snakeyaml\1.27\snakeyaml-1.27.jar;D:\RepMaven\org\springframework\boot\spring-boot-starter-json\2.4.4\spring-boot-starter-json-2.4.4.jar;D:\RepMaven\com\fasterxml\jackson\core\jackson-databind\2.11.4\jackson-databind-2.11.4.jar;D:\RepMaven\com\fasterxml\jackson\core\jackson-annotations\2.11.4\jackson-annotations-2.11.4.jar;D:\RepMaven\com\fasterxml\jackson\core\jackson-core\2.11.4\jackson-core-2.11.4.jar;D:\RepMaven\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.4\jackson-datatype-jdk8-2.11.4.jar;D:\RepMaven\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.4\jackson-datatype-jsr310-2.11.4.jar;D:\RepMaven\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.4\jackson-module-parameter-names-2.11.4.jar;D:\RepMaven\org\springframework\boot\spring-boot-starter-tomcat\2.4.4\spring-boot-starter-tomcat-2.4.4.jar;D:\RepMaven\org\apache\tomcat\embed\tomcat-embed-core\9.0.44\tomcat-embed-core-9.0.44.jar;D:\RepMaven\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;D:\RepMaven\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.44\tomcat-embed-websocket-9.0.44.jar;D:\RepMaven\org\springframework\spring-web\5.3.5\spring-web-5.3.5.jar;D:\RepMaven\org\springframework\spring-beans\5.3.5\spring-beans-5.3.5.jar;D:\RepMaven\org\springframework\spring-webmvc\5.3.5\spring-webmvc-5.3.5.jar;D:\RepMaven\org\springframework\spring-aop\5.3.5\spring-aop-5.3.5.jar;D:\RepMaven\org\springframework\spring-context\5.3.5\spring-context-5.3.5.jar;D:\RepMaven\org\springframework\spring-expression\5.3.5\spring-expression-5.3.5.jar;D:\RepMaven\mysql\mysql-connector-java\8.0.23\mysql-connector-java-8.0.23.jar;D:\RepMaven\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;D:\RepMaven\org\springframework\spring-core\5.3.5\spring-core-5.3.5.jar;D:\RepMaven\org\springframework\spring-jcl\5.3.5\spring-jcl-5.3.5.jar;D:\JetBrains\IntelliJ IDEA 2020.3\lib\idea_rt.jar" com.yg.datastructures.queue.ArrayQueueTest
Connected to the target VM, address: '127.0.0.1:14148', transport: 'socket'
----------------程序开始----------------------
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------


a
请输入添加的元素:
1111
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
a
请输入添加的元素:
2222
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
a
请输入添加的元素:
333
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
a
请输入添加的元素:
444
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
g
头部元素 =1111
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
s
-------------------开始打印队列-------------------
2222
333
444
null
null
-------------------结束打印队列-------------------
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
h
队列的头部元素是:2222
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
g
头部元素 =2222
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
s
-------------------开始打印队列-------------------
333
444
null
null
null
-------------------结束打印队列-------------------
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
h
队列的头部元素是:333
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
s
-------------------开始打印队列-------------------
333
444
null
null
null
-------------------结束打印队列-------------------
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
a
请输入添加的元素:
5555
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
s
-------------------开始打印队列-------------------
333
444
5555
null
null
-------------------结束打印队列-------------------
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------


g
头部元素 =333
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
s
-------------------开始打印队列-------------------
444
5555
null
null
null
-------------------结束打印队列-------------------
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
a
请输入添加的元素:
6666
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
a
请输入添加的元素:
777
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
s
-------------------开始打印队列-------------------
444
5555
6666
777
null
-------------------结束打印队列-------------------
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
h
队列的头部元素是:444
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
g
头部元素 =444
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
h
队列的头部元素是:5555
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
h
队列的头部元素是:5555
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
h
队列的头部元素是:5555
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
h
队列的头部元素是:5555
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------

h
队列的头部元素是:5555
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
s
-------------------开始打印队列-------------------
5555
6666
777
null
null
-------------------结束打印队列-------------------
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
a
请输入添加的元素:
888
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
s
-------------------开始打印队列-------------------
5555
6666
777
888
null
-------------------结束打印队列-------------------
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
h
队列的头部元素是:5555
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
h
队列的头部元素是:5555
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
h
队列的头部元素是:5555
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
g
头部元素 =5555
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
s
-------------------开始打印队列-------------------
6666
777
888
null
null
-------------------结束打印队列-------------------
---------------控制台----------------
s(show) : 展示队列
e(exit) : 退出队列
a(add) : 添加队列
g(get) : 获取队列头部元素
h(head) : 展示队列头部元素
---------------控制台----------------
e
----------------程序结束----------------------
Disconnected from the target VM, address: '127.0.0.1:14148', transport: 'socket'

Process finished with exit code 0

解决方法2:
采用环形数组模拟队列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值