数据结构与算法之队列

一、队列初识

队列的基本特性就是先进先出(FIFO)。也就是第一个进去的元素,第一个出来。队列就是一个只允许在一端进行插入,在另一端进行删除操作的线性表。

image

二、队列的代码实现

1.顺序队列

public class ArrayQueue<T> {
    private T[] data;
    private int size;//元素个数
    private int front;//队列中第一个对象的位置
    private int rear;//队列中当前对象的位置
    //初始化方法
    public ArrayQueue() {
        data = (T[]) new Object[10];
        size = 0;
        front =0;
        rear = 0;
    }
    //增加元素
    public void add(T t) {
        if(isFull()){
            resize();
            front = 0;
        }
        rear = (front+size)%data.length;
        System.out.println(rear);
        data[rear] = t;
        size++;
    }
    //删除元素
    public T remove() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空!");
        }
        T tempData = data[front];
        data[front] = null;
        front = (front + 1) % (data.length);
        size--;
        return tempData;
    }
    //取得队列大小
    public int size() {
        return size;
    }
    public boolean isEmpty() {
        return size == 0;
    }
    //判断当前队列是否已满
    public boolean isFull(){
        return size == data.length;
    }
    //取得当前队头元素
    public T front() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空!");
        }
        return data[front];
    }

    //扩容
    public void resize(){
        /*注意重新扩容的时候并不需要去设置size
         * 队列的大小并不能通过数组的大小直观的显示出来。
         * 但是栈就可以直观的通过数组的大小显示出来*/
        T[] tmp = (T[]) new Object[data.length*2];
        System.arraycopy(data, 0, tmp, 0, data.length);
        data = tmp;
        tmp = null;//引用置为空,便于gc处理
    }
}

2.链式队列

首先,定义一个节点对象

public class QueueNode<Item> {

    Item item;
    QueueNode nextNode;

    public Item getItem() {
        return item;
    }

    public void setItem(Item item) {
        this.item = item;
    }

    public QueueNode getNextNode() {
        return nextNode;
    }

    public void setNextNode(QueueNode nextNode) {
        this.nextNode = nextNode;
    }
}

然后,实现链式队列:

public class QueueList<Item> implements Iterable<Item>{
    private QueueNode first;
    private QueueNode last;
    private int nodeNum;

    public boolean isEmpty(){
        return first == null;
    }
    public int size(){
        return nodeNum;
    }
    //加入队列
    public void enqueue(Item item){
        QueueNode oldLast = last;
        last = new QueueNode();
        last.item = item;
        last.nextNode = null;
        if (isEmpty()){
            first = last;
        } else{
            oldLast.nextNode = last;
        }
        nodeNum++;
    }
    //出列
    public Item dequeue(){
        Item item = (Item) first.item;
        first = first.nextNode;
        if (isEmpty()){
            last = null;
        }
        nodeNum--;
        return item;
    }
    @Override
    public Iterator<Item> iterator(){
        return new LinkListIterator();
    }

    public class LinkListIterator implements Iterator<Item>{
        QueueNode node = first;

        @Override
        public boolean hasNext(){
            return node.nextNode != null;
        }
        @Override
        public Item next(){
            Item item = (Item) node.item;
            node = node.nextNode;
            return item;
        }
        @Override
        public void remove() {
            dequeue();
        }
    }
}

三、队列的总结
以上就是顺序队列和链式队列的基本实现。通过代码我们可以得知链式队列与顺序队列不同,每个节点不仅保存当前元素的值,还有指向下一个元素的指针。

posted @ 2022-01-27 11:11  背影1130  阅读(18)  评论(0)    收藏  举报