队列是对类似排队现象的抽象,一头只能进数据,另一头只能出数据,遵守“先进先出”的规则。底层可以有顺序存储和链式存储两种实现方式,本文以顺序存储为例讲解并通过Java编程实现入队、出队的基本功能,考虑不周的地方欢迎讨论交流。

顺序存储即按数组存储,特点是开辟的数组空间是定死的,一般不采取走一个元素就把所有元素往前挪一步的做法,而是让它们各自还在自己的位置上。队尾不断有元素加进来,队头有元素出队而产生空缺,这就造成一个问题,那就是可能会出现队尾到了数组末尾(队满),而队头实际上有空缺的现象(实际没满)。循环队列就是为了解决这个问题,我们可以想象一个车轮子,队列在上面一圈一圈地排,只要首尾不相接就永远没有“假溢出”的现象。但本质上还是个一维数组,只是头尾指针到了数组末尾会自动回到开头,好像一个环一样。

头指针指向最先进来的元素,当要出队时就“释放”头指针所指元素,该指针指向后一个元素。这里并不是真的释放,数据实际上还在那个位置,只不过通过指针的移动放弃了它,下次新的数据会把它覆盖掉。尾指针指向即将入队的位置,即最后一个入队元素的下一个位置。

判断队列是否为空很简单,只要看看首尾指针是否指向同一个地址即可。判断队列是否为满就有讲究了,毕竟空和满的首尾指针相对位置差不多。一种解决思路是空出一个存储单元不存储数据,专门用来防止首尾指针因队满再次相遇。这样,队满时尾指针应该指向这个空位置,而头指针在它的下一个位置,从而很好地和队空进行了区分。

这里我们以4个存储空间的数组为例,演示循环队列实现过程。依次进行添加1、2、3,删除1、2、3,添加4、5,删除4的操作,观察整个存储空间和首尾指针的位置变化情况。

java简单队列执行任务怎么写 java实现任务队列_队列


利用代码模拟,运行结果如下图所示。

java简单队列执行任务怎么写 java实现任务队列_System_02


可以看到,结果还是一致且准确的。附上核心代码。出入队列时加上了队空队满的判断,满时入队、空时出队都会抛出异常。

public class Queue {

    private static final int MAXSIZE = 4; //最大空间
    private int[] queue; //队列
    private int frontPointer, rearPointer; //头尾指针

    public Queue() {
        queue = new int[MAXSIZE];
        frontPointer = 0;
        rearPointer = 0;
    }

    //判断为空
    public boolean isEmpty() {
        return frontPointer == rearPointer;
    }

    //判断为满
    public boolean isFull() {
        return frontPointer == (rearPointer + 1) % MAXSIZE;
    }

    //入队
    public void enQueue(int element) {
        if (isFull()) throw new RuntimeException("队列为满!");
        queue[rearPointer] = element;
        rearPointer = (rearPointer + 1) % MAXSIZE;
    }

    //出队
    public void deQueue() {
        if(isEmpty()) throw new RuntimeException("队列为空!");
        frontPointer = (frontPointer + 1) % MAXSIZE;
    }

    //打印队列
    public void show() {
        //显示有效队列
        System.out.print("当前排队情况:");
        int i = frontPointer;
        while(i % MAXSIZE != rearPointer)  {
            System.out.print(queue[i % MAXSIZE]);
            i+=1;
        }
        System.out.print('\n');
        //显示队列存储全部情况
        System.out.print("队列总体情况:");
        for(int j = 0; j < 4; j++) {
            System.out.print(queue[j]);
        }
        System.out.println(" front=" + frontPointer + " rear=" + rearPointer + '\n');
    }
}