链表队列 顺序队列(基于数组) 循环队列(基于数组)

链表队列

public class QueueBasedOnLinkedList {

    public static class Node {
        int data;
        Node next;

        public Node(int data, Node next) {
            this.data = data;
            this.next = next;
        }

        public int getData() {
            return data;
        }
    }

    private Node head;
    private Node tail;

    public QueueBasedOnLinkedList() {
        head = null;
        tail = null;
    }

    // 入队
    public void enqueue(int value) {
        Node newNode = new Node(value, null);
        if (tail == null) {
            head = tail = newNode;
        } else {
            tail.next = newNode;
            tail = newNode;
        }
    }

    public int dequeue() {
        if (head == null) return -1;
        int value = head.getData();
        head = head.next;
        if (head == null) {
            tail = null;
        }
        return value;
    }


    public void printAll() {
        Node p = head;
        while (p != null) {
            System.out.println(p.data + " ");
            p = p.next;
        }
        System.out.println("------------end-------------");
    }
}

顺序队列


public class ArrayQueue {
    private String[] items;
    private int n = 0;//代表数组大小
    private int head = 0;//队列头下标
    private int tail = 0;//队尾下标

    public ArrayQueue(int capacity) {
        items = new String[capacity];
        n = capacity;
    }

    //申请入队
    public boolean enqueue(String item) {
        if (tail == n) {
            if (head == 0) return false;//整个队列已经满了
            // 数据搬移
            for (int i = head; i < tail; ++i) {
                items[i - head] = items[i];
            }
            tail-=head;
            head = 0;
        }

        items[tail++] = item;

        return true;
    }

    //出队
    public String dequeue() {
        if (head == tail) return null;
        String ret = items[head++];
        return ret;
    }
}

 循环队列

数组来实现队列的时候,在 tail==n 时,会有数据搬移操作,这样入队操作性能就会受到影响。那有没有办法能够避免数据搬移呢?我们来看看循环队列的解决思路。

顾名思义,它长得像一个环。原本数组是有头有尾的,是一条直线。现在我们把首尾相连,扳成了一个环

public class CircularQueue {
    private String[] items;
    private int n = 0;
    private int head = 0;
    private int tail = 0;

    public CircularQueue(int cap) {
        items = new String[cap];
        n = cap;
    }

    //入队
    public boolean enqueue(String item) {
        if ((tail + 1) % n == head) return false;

        items[tail] = item;

        tail = (tail+1) % n;
        return true;
    }


    //出队
    public String dequeue(){
        if(head == tail) return null;

        String ret = items[head];

        head = (head+1) % n;

        return ret;
    }

}

阻塞队列其实就是在队列基础上增加了阻塞操作。简单来说,就是在队列为空的时候,从队头取数据会被阻塞。因为此时还没有数据可取,直到队列中有了数据
才能返回;如果队列已经满了,那么插入数据的操作就会被阻塞,直到队列中有空闲位置后再插入数据,然后再返回

 

线程安全的队列我们叫作并发队列。最简单直接的实现方式是直接在enqueue()、dequeue()方法上加锁,但是锁粒度大并发度会比较低,同一时刻仅允许一个存或
者取操作。实际上,基于数组的循环队列,利用 CAS 原子操作,可以实现非常高效的并发队列

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值