队列(Queue)

243 阅读1分钟

队列(queue) :只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
队列是一种先进先出(First In First Out)的线性表,简称FIFO
允许插入的一端称为队尾,允许删除的一端称为队头

image.png

循环队列

image.png

基本操作

  1. EnQueue:插入新元素并作为队尾元素。
  2. DeQueue:从队列头部删除一个元素,同时返回该元素。
  3. front() or peek():返回队头元素。
  4. IsEmpty()

以上操作时间复杂度为O(1)

使用场景

一个典型的使用场景,多个请求同时请求同一共享资源,该资源同时只能处理一个请求,比较合理的方式就是让请求排队,先请求的先处理,比如打印机。

image.png

实现

数组实现

public class CircleQueue {
    private int[] items;
    private int n;
    
    private int head = 0;
    private int tail = 0;
    
    public Circle(int capcity) {
        items = new int[capcity];
        n = capcity;
    }
    
    public void enqueue(int x) {
        if(head == (tail + 1) % n) {
            // queue is full
            return;
        }
        
        items[tail] = x;
        tail = (tail + 1) % n;
        
    }
    
    public int dequeue() {
        if(isEmpty()) {
            throw new EmptyQueueExceptiion();
        }
        
        int value =  items[head];
        head = (head + 1) % n;
        return value;
    }
    
    public boolean isEmpty() {
        return head == tail;
    }
}

链表实现

public class LinkedQueue {
    private ListNode head;
    private ListNode tail;
    
    public void enqueue(int x) {
        ListNode node = new ListNode();
        node.value = x;
        if(head == null) {
            head = tail = node;
        } else {
            tail.next = node;
            tail = node;
        }
    }
    
    public int dequeue() {
        if(isEmpty()) {
            threw new EmptyQueueException();
        }
        int v = head.value;
        head = head.next;
        if(head == null) {
            tail = null;
        }
        return v;
    }
    
    public boolean isEmpty() {
        return head == null;
    }
    
}