Java实现环形队列

这里我定义的环形队列为:列表中最后一个元素是指向列表中的第一个元素,而且里面提供一个next方法,可以不断获取下一个元素,在环形队列中也就是不断的转圈,实现方式如下:

队列中提供的方法:

算法与数据结构技术学习,更多知识请访问https://www.itkc8.com

public boolean add(E e):加入队列
public E next():加入返回当前指针元素并把指针指向下一个元素
public E prev():返回当前元素,并把指针指向上一个元素
remove(E e):删除队列中某一个元素
  • 1
  • 2
  • 3
  • 4

完整的实现代码如下:

public class CircularQueue<E> {
    private int size;

    //指针
    private Node<E> node;

    private Node<E> first;
    private Node<E> last;

    private final int MODE_NEXT = 0;
    private final int MODE_PREV = 1;
    private int lastMode = MODE_NEXT; //最后一次操作,0为next,1为prev



    public CircularQueue() {

    }

    /**
     * 加入队列
     * @param e
     */
    public boolean add(E e){
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, first);
        last = newNode;

        if (node == null) node = newNode; //指针
        if (l == null) {
            first = newNode;
            first.prev = first;
        }
        else {
            l.next = newNode;
            first.prev = l.next;
        }

        size++;
        return true;
    }

    /**
     * 返回当前指针元素并把指针指向下一个元素
     * @return
     */
        public E next() {
        if (node == null) {
            return null;
        }
        E e = node.item;
        node = node.next;

        lastMode = MODE_NEXT;
        return e;
    }

    /**
     * 返回当前元素,并把指针指向上一个元素
     * @return
     */
    public E prev() {
        if (node == null) {
            return  null;
        }
        E e = node.item;
        node = node.prev;

        lastMode = MODE_PREV;
        return e;
    }

    /**
     * 删除队列中某一个元素
     * @param e
     * @return
     */
    public boolean remove(E e) {
        if (e == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (e.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }

        size--;
        return true;
    }

    public E peek(){
        return node.item;
    }

    /**
     * 删除节点
     */
    E unlink(Node<E> x) {
        final E element = x.item;
        final Node<E> next = x.next;
        final Node<E> prev = x.prev;

        if (prev == x || next == x) {
            this.first = null;
            this.last = null;
            this.node = null;
        }

        next.prev = prev;
        prev.next = next;

        if ((element==null&&this.node.item==null) || (element.equals(this.node.item))) {
            this.node = lastMode==MODE_NEXT ? this.node.next : this.node.prev;
        }

        x.item = null;
        x = null;
        size--;
        return element;
    }

    public int size() {
        return size;
    }


    /**
     * 节点类
     * @param <E>
     */
    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

}

 

如果在高并发的情况下需要实现线程同步的环形队列,只需要继承上面的类,为需要同步的方法加锁即可:

import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by giant039 on 2017/3/17.
 */
public class CircularBlockingQueue<E> extends CircularQueue<E> {
    /** 对添加,删除,指针移动操作加锁 */
    protected final ReentrantLock putLock = new ReentrantLock();

    private QueueListener listener;

    public CircularBlockingQueue() {
        super();
    }

    public CircularBlockingQueue(QueueListener listener) {
        super();
        this.listener = listener;
    }

    public void setListener(QueueListener listener) {
        this.listener = listener;
    }

    @Override
    public boolean add(E e) {
        final ReentrantLock putLock = this.putLock;
        try {
            putLock.lockInterruptibly();
            super.add(e);

            if (listener != null) listener.afterAdd(e);

            return true;
        } catch (InterruptedException exp) {
            exp.printStackTrace();
            return false;
        } finally {
            putLock.unlock();
        }

    }

    @Override
    public E next() {
        final ReentrantLock putLock = this.putLock;
        try {
            putLock.lockInterruptibly();
            return super.next();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return null;
        } finally {
            putLock.unlock();
        }

    }

    @Override
    public E prev() {
        final ReentrantLock putLock = this.putLock;
        try {
            putLock.lockInterruptibly();
            return super.prev();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return null;
        } finally {
            putLock.unlock();
        }
    }

    @Override
    public boolean remove(E e) {
        final ReentrantLock putLock = this.putLock;
        try {
            putLock.lockInterruptibly();

            if (listener != null) listener.afterAdd(e);

            return super.remove(e);
        } catch (InterruptedException exp) {
            exp.printStackTrace();
            return false;
        } finally {
            putLock.unlock();
        }
    }


    /**
     * 监听器监听插入,删除,等操作之后需要实现的功能
     */
    interface QueueListener<E> {
        void afterAdd(E e);
        void afterRemove(E e);
    }

}

 

算法与数据结构技术学习,更多知识请访问https://www.itkc8.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值