使用数组实现队列

简介: 队列是一种数据存储的结构,实例化的队列就是一种数据容器,用特定的规则来存储数据的容器。队列遵循先进先出原则,一般可以使用数组和链表来实现队列,且队列的进队只从屁股rear开始,出列从front开始。

什么是队列



队列是一种数据存储的结构,实例化的队列就是一种数据容器,用特定的规则来存储数据的容器。队列遵循先进先出原则,一般可以使用数组和链表来实现队列,且队列的进队只从屁股rear开始,出列从front开始。


队列实现需要注意哪些?



队列必须的属性需要有实现数据存储的容器、队列的容量、rear以及front。方法需要有进队方法,以及出对方法。此外进队需要判断队列是否已满,出对判断队列是否已空等,这便是实现一个队列的基本关注点。此外,往细了考虑,什么情况是队列满了呢?初始时队列为空,rear与front均是-1,rear的取值范围是-1 到 maxSize-1.而front的取值范围也是-1到maxSize。队列满时则rear必须是maxSize-1且front!=rear,而队列为空时,则一定是rear=front时。


记录代码实现



class  PQueue{
    private static PQueue pQueue;
    private int[] array;//声明一个数组,用作这个队列的容器
    private int maxSize;//队列的大小
    private int rear;//队列的后端,初始-1
    private int front;//队列的前端-1(front永远指向队列的前一个数),初始-1
    //初始化队列--禁止外部调用
    private PQueue(int maxSize){
        this.maxSize = maxSize;
        array = new int[this.maxSize];
        rear = -1;
        front = -1;
    }
    //线程安全的单利模式
    public static  PQueue getInstance(int maxSize){
        if(null == pQueue){
            synchronized (PQueue.class){
                pQueue = new PQueue(maxSize);
            }
        }
        return pQueue;
    }
    //判断队列是否已满
    public boolean isFull(){
        return rear == maxSize-1?false:true && rear!=front;
    }
    //判断队列是否为空
    public synchronized boolean isEmpty(){
        return rear == front?false:true;
    }
    //队列中增加元素
    public void addPQueue(int num){
        //先判断队列已满
        if(isFull()){
            rear++;
            array[rear]=num;
            return;
        }
        System.out.println("队列已满,添加元素失败");
        throw new RuntimeException("队列已满,添加元素失败");
    }
    //队列中删除元素--可能会有多个线程同时操作,需线程安全
    public synchronized int getPQueue(){
        //判断队列是否为空
        if(isEmpty()){
            front++;
            return array[front];
        }
        System.out.println("队列为空,删除元素失败");
        throw new RuntimeException("队列为空,删除元素失败");
    }
    //展示队列中所有元素
    public int[] showPQueue(){
        //数组长度为rear减去front,因front指向数组的前一个值
        int[] realArray = new int[rear-front];
        int index=0;//初始化realArray的下标。
        for(int i=0;i<array.length;i++){
            //将有效的数据加入到真实数组中
            if(i>front && i<=rear){
                realArray[index]=array[i];
                index++;
            }
        }
        return realArray;
    }
}


队列的应用场景在哪?



1.最常见的就是排队系统,你必须保证先取号的人,最先被服务,这种常见的就是各个银行等。这里模拟下银行排队系统(线程通信并未实现,有线程安全风险)


代码如下


//模拟银行业务的线程A
class OperatorA implements Runnable{
PQueue pQueue = PQueue.getInstance(20);
    @Override
    public void run() {
        while (pQueue.isEmpty()){
            System.out.println("请"+pQueue.getPQueue()+"号客户前往A窗口办理业务!");
            System.out.println("业务处理中。。。");
            try {
                Thread.currentThread().sleep(3000);//假设A窗口处理业务需要3秒钟
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//模拟银行业务的线程B
class OperatorB implements Runnable{
    PQueue pQueue = PQueue.getInstance(20);
    @Override
    public void run() {
        while(pQueue.isEmpty()){
            System.out.println("请"+pQueue.getPQueue()+"号客户前往B窗口办理业务!");
            System.out.println("业务处理中。。。");
            try {
                Thread.currentThread().sleep(4000);//假设B窗口处理业务需要4秒钟
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//模拟银行业务的线程C
class OperatorC implements Runnable{
    PQueue pQueue = PQueue.getInstance(20);
    @Override
    public void run() {
        while(pQueue.isEmpty()){
            System.out.println("请"+pQueue.getPQueue()+"号客户前往C窗口办理业务!");
            System.out.println("业务处理中。。。");
            try {
                Thread.currentThread().sleep(5000);//假设C窗口处理业务需要5秒钟
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


执行代码



PQueue pQueue = PQueue.getInstance(13);
        //假设有13个人取了票在排队
        pQueue.addPQueue(1);
        pQueue.addPQueue(2);
        pQueue.addPQueue(3);
        pQueue.addPQueue(4);
        pQueue.addPQueue(5);
        pQueue.addPQueue(6);
        pQueue.addPQueue(7);
        pQueue.addPQueue(8);
        pQueue.addPQueue(9);
        pQueue.addPQueue(10);
        pQueue.addPQueue(11);
        pQueue.addPQueue(12);
        pQueue.addPQueue(13);
        //银行窗口开始工作
        Thread threadA = new Thread(new OperatorA());
        Thread threadB = new Thread(new OperatorB());
        Thread threadC = new Thread(new OperatorC());
        threadA.start();
        threadB.start();
        threadC.start();


执行结果



请1号客户前往A窗口办理业务!
业务处理中。。。
请2号客户前往C窗口办理业务!
业务处理中。。。
请3号客户前往B窗口办理业务!
业务处理中。。。
请4号客户前往A窗口办理业务!
业务处理中。。。
请5号客户前往B窗口办理业务!
业务处理中。。。
请6号客户前往C窗口办理业务!
业务处理中。。。
请7号客户前往A窗口办理业务!
业务处理中。。。
请8号客户前往B窗口办理业务!
业务处理中。。。
请9号客户前往A窗口办理业务!
业务处理中。。。
请10号客户前往C窗口办理业务!
业务处理中。。。
请11号客户前往A窗口办理业务!
业务处理中。。。
请12号客户前往B窗口办理业务!
业务处理中。。。
请13号客户前往C窗口办理业务!
业务处理中。。。
相关文章
|
7月前
|
索引
队列的数组实现
队列的数组实现
28 0
|
7月前
|
存储 算法
数据结构和算法学习记录——特殊线性表之队列-队列的概念、队列结构体类型定义 、基本接口函数、初始化函数、销毁队列函数、入队列函数、判断队列是否为空、出队列函数、读取队头队尾的数据 、计算队列数据个数
数据结构和算法学习记录——特殊线性表之队列-队列的概念、队列结构体类型定义 、基本接口函数、初始化函数、销毁队列函数、入队列函数、判断队列是否为空、出队列函数、读取队头队尾的数据 、计算队列数据个数
53 0
|
8月前
|
缓存
队列的实现及操作(链表实现)
队列的实现及操作(链表实现)
|
8月前
|
存储
队列的学习(一)用数组和链表实现单向队列
队列的学习(一)用数组和链表实现单向队列 队列(Queue)是一种先进先出的数据结构,类似于现实生活中排队的场景。它有两个基本操作:入队(enqueue)和出队(dequeue)。在本文中,我们将介绍如何使用数组和链表来实现单向队列。
|
消息中间件 前端开发 JavaScript
使用数组实现队列
使用数组实现队列
66 0
|
算法 调度 C++
队列(Queue):先进先出的数据结构队列
队列(Queue):先进先出的数据结构队列
226 0
7.5 C/C++ 实现链表队列
链表队列是一种基于链表实现的队列,相比于顺序队列而言,链表队列不需要预先申请固定大小的内存空间,可以根据需要动态申请和释放内存。在链表队列中,每个节点包含一个数据元素和一个指向下一个节点的指针,头节点表示队头,尾节点表示队尾,入队操作在队尾插入元素,出队操作在队头删除元素,队列的长度由节点数量决定。由于链表队列没有容量限制,因此可以处理任意数量的元素,但是相比于顺序队列,链表队列的访问速度较慢,因为需要通过指针来访问下一个节点。
|
存储
瞬解 队列 -- 循环队列问题(超超超详解)
瞬解 队列 -- 循环队列问题(超超超详解)
77 0
队列的定义、基本操作、顺序实现(初始化,入队,出队)
数据结构:队列的定义、基本操作、顺序实现(初始化,入队,出队)附有代码讲解
742 0
|
C# C++ 索引
用C#构造一个队列Queue。要求此队列是循环队列,并进行入队、出队的测试。
用C#构造一个队列Queue。要求此队列是循环队列,并进行入队、出队的测试。
219 0
用C#构造一个队列Queue。要求此队列是循环队列,并进行入队、出队的测试。