使用数组实现队列

什么是队列?

队列是一种数据存储的结构,实例化的队列就是一种数据容器,用特定的规则来存储数据的容器。队列遵循先进先出原则,一般可以使用数组和链表来实现队列,且队列的进队只从屁股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窗口办理业务!
业务处理中。。。

猜你喜欢

转载自blog.csdn.net/m0_46897923/article/details/107690852