美文网首页
写一个环形队列

写一个环形队列

作者: 无聊之园 | 来源:发表于2019-06-18 10:54 被阅读0次

背景:有一个人接收到的一个面试题,说写一个环形队列。

其实它描述的并非环形队列,而是普通的ArrayQueue。

先贴代码.
这里,队列空,dequeue会报错,队列满,enqueue会报错。
你会发现,这个跟arrayQueue,几乎一样,看起来是环形的结构,但是总感觉不对劲。
而且,你去看arrayQueue的源代码,会发现,思想几乎一样。。。
只是,少了arrayQueue的扩容机制。

public class DiyArrayQueue implements Queue {

    private static final int MAX_ARRAY_SIZE = 65536;

    private Object[] items;

    // 头节点,get的位置
    private int front;

    // 尾节点,put的位置
    private int rear;

    public DiyArrayQueue(int initQueueSize){
        // 容量+1,因为,尾节点永远不会追上头节点,也就是实际容量少了1.
        items = new Object[initQueueSize + 1];
        this.rear = 0;
        this.front = 0;
    }


    @Override
    public boolean enqueue(Object o) {
        int tmp = rear;
        if(++tmp == items.length){
            tmp = 0;
        }
        if(tmp == front){
            throw new RuntimeException("队列是满的");
        }
        rear = tmp;
        items[rear] = o;
        return true;
    }

    @Override
    public Object dequeue() {
        if(rear == front){
            throw new RuntimeException("队列是空的");
        }
        int tmp = front + 1;
        if(tmp == items.length){
            tmp = 0;
        }
        Object o = items[tmp];
        if(o == null){
            return null;
        }
        front = tmp;
        return o;
    }

    @Override
    public int size() {
        if(rear == front){
            return 0;
        }
        int size = rear - front;
        if(size < 0){
            return items.length - front + rear;
        }
        return size;
    }
}

我觉得,要环形队列,最起码,应该是会一直循环的吧,比如,可以一直enqueue。
像这样:
虽然我觉得这样也不对。

public class CircleQueue implements Queue {

    private static final int MAX_ARRAY_SIZE = 65536;

    private Object[] items;

    // 头节点,get的位置
    private int front;

    // 尾节点,put的位置
    private int rear;

    public CircleQueue(int initQueueSize){
        items = new Object[initQueueSize];
        this.rear = 0;
        this.front = 0;
    }


    @Override
    public boolean enqueue(Object o) {
        if(++rear == items.length){
            rear = 0;
        }
        items[rear] = o;
        return true;
    }

    @Override
    public Object dequeue() {
        int tmp = front + 1;
        if(tmp == items.length){
            tmp = 0;
        }
        Object o = items[tmp];
        if(o == null){
            return null;
        }
        front = tmp;
        // 设置空
        items[tmp] = null;
        return o;
    }

    @Override
    public int size() {
        // 空和full这两个指针都是指向相同的元素
        if(rear == front){
            // 如果有一个元素为null,则说明null的
            if( null == items[0]){
                return 0;
            }
            return items.length;
        }
        int size = rear - front;
        if(size < 0){
            return items.length - front + rear;
        }
        return size;
    }
}

总结:
1、这种数据结构,必须要定位使用场景,否则,很容易出现误解。
比如环形队列在延迟队列中得使用,就会是另一个环形队列得数据结构了。
2、而且,比如,有时候环形队列用链表会更合适,没有扩容得烦扰什么的。

相关文章

  • 写一个环形队列

    背景:有一个人接收到的一个面试题,说写一个环形队列。 其实它描述的并非环形队列,而是普通的ArrayQueue。 ...

  • 数组实现环形队列

    利用数组结构在队列的基础下用取模算法来实现环形队列。 环形队列拥有复用功能。 主要算法思想:1)front指向队列...

  • 2020-11-10-数据结构与算法-14(队列scala版)

    1.队列 非环形实现 2.队列环形版 核心思想: 用%来模拟循环(rear +1) /maxsize = firs...

  • 环形队列

    写完这篇文章想着以后尽量(应该说一定)使用现在正在使用的LPC系列的单片机写程序,其实内心感觉还是LPC做的相当完...

  • 环形队列

    1、概念 环形队列是一个最为简单的数据结构,底层用数组组成,然后逻辑上数组首尾相连。虽然他的结构极为简单,但是用处...

  • 环形队列

    利用数组通过取模的方式实现环形队列,使队列达到复用的效果。 图1中,rear和front分别代表队尾和队头并且初始...

  • workQueue有以下七种选择

    : ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列(数组结构可配合指针实现一个环形队列)。...

  • 数据结构之队列

    什么是队列 队列是一个有序列表, 可以用数组或链表实现 先入先出 使用数组模拟队列和环形队列 用数组模拟队列 思路...

  • C++数据结构探险——队列篇

    数据结构的原理 队列:先进先出(FIFO:first in first out) 普通队列: 环形队列: 以C++...

  • 数据结构

    稀疏数组 代码实现: 队列 代码实现: 环形队列 什么时候队列满:(rear+1)%maxsize == fron...

网友评论

      本文标题:写一个环形队列

      本文链接:https://www.haomeiwen.com/subject/jjvxqctx.html