數據結構-3-隊列

三、隊列

1、概念

隊列是一種遵循 FIFO(first-in-first-out)的集合數據結構,即最先放到隊列中的元素,也是最先被獲取到的

它底層可以用數組來實現,也可以用鏈表來實現。它有2個指針,分別指向頭節點和尾節點,添加元素時向後移動尾節點,移除元素時向後移動頭節點

2、常用方法

  1. put 添加元素到隊列中
  2. take 移出隊列的首個元素(向後移動頭節點)
  3. peek 取出隊列的首個元素(不移動頭節點)

3、示例

1)數組隊列

class ArrayQueue<T> {
    private final int length;
    private Object[] array;
    private int head; // 指向本次要移出的元素的前一個位置
    private int tail; // 指向本次要添加的元素的前一個位置

    public ArrayQueue(int length) {
        this.length = length;
        this.array = new Object[this.length];
        this.head = -1;
        this.tail = -1;
    }

    public void put(T element) {
        if (isFull()) {
            return;
        }

        this.tail++;
        array[tail] = element;
    }

    public T take() {
        if (isEmpty()) {
            return null;
        }

        this.head++;
        @SuppressWarnings("unchecked")
        T element = (T)array[head];
        if (head == tail) {
            head = -1;
            tail = -1;
        }
        return element;
    }

    @SuppressWarnings("unchecked")
    public T peek() {
        if (isEmpty()) {
            return null;
        }
        return (T)array[head + 1];
    }

    public int size() {
        return tail - head;
    }

    @Override
    public String toString() {
        if (isEmpty()) {
            return "[]";
        }

        StringBuilder sBuilder = new StringBuilder("[");
        for (int i = head + 1, size = i + size(); i < size; i++) {
            sBuilder.append(array[i]);
            if (i != size - 1) {
                sBuilder.append(", ");
            } else {
                sBuilder.append("]");
            }
        }
        return sBuilder.toString();
    }

    public boolean isFull() {
        return tail == length - 1;
    }

    public boolean isEmpty() {
        return -1 == head && head == tail;
    }

}

2)鏈表隊列

class LinkedQueue<T> {
    private final int length;
    private Node<T> head; // 頭節點指向本次可以取出的節點
    private Node<T> tail; // 尾節點指向最後一個節點
    private int size;

    public LinkedQueue(int length) {
        this.length = length;
        this.head = null;
        this.tail = null;
        this.size = 0;
    }

    public void put(T element) {
        if (isFull()) {
            return;
        }

        Node<T> add = new Node<T>(element);
        if (null == head) {
            this.head = add;
        }
        if (null != tail) {
            tail.next = add;
        }
        this.tail = add;
        this.size++;
    }

    public T take() {
        if (isEmpty()) {
            return null;
        }

        T element = head.element;
        if (head == tail) { // 最後一個元素,將尾節點也置爲空
            this.tail = null;
        }
        this.head = head.next;
        this.size--;
        return element;
    }

    public T peek() {
        if (isEmpty()) {
            return null;
        }
        return head.element;
    }

    public int size() {
        return size;
    }

    @Override
    public String toString() {
        if (isEmpty()) {
            return "[]";
        }

        StringBuilder sBuilder = new StringBuilder("[");
        Node<T> node = this.head;
        while (true) {
            sBuilder.append(node.element);
            if (null == node.next) {
                break;
            }
            sBuilder.append(", ");
            node = node.next;
        }
        sBuilder.append("]");
        return sBuilder.toString();
    }

    public boolean isFull() {
        return size == length;
    }

    public boolean isEmpty() {
        return 0 == size;
    }

    private static class Node<T> {
        private final T element;
        private Node<T> next;

        private Node(T element) {
            this.element = element;
        }

        @Override
        public String toString() {
            return (null != element) ? element.toString() : "null";
        }
    }

}

3)循環隊列

class CircleQueue<T> {
    private final int length;
    private Object[] array;
    private int head; // 指向隊頭
    private int tail; // 指向隊尾

    public CircleQueue(int length) {
        this.length = length + 1; // 多出一個位置,用於存放上一次取出的元素。更新指針時訪問不到它
        this.array = new Object[this.length];
        this.head = 0;
        this.tail = 0;
    }

    public void put(T element) {
        if (isFull()) {
            return;
        }

        array[tail] = element;
        tail = (tail + 1) % length;
    }

    public T take() {
        if (isEmpty()) {
            return null;
        }

        @SuppressWarnings("unchecked")
        T element = (T)array[head];
        head = (head + 1) % length;
        return element;
    }

    @SuppressWarnings("unchecked")
    public T peek() {
        if (isEmpty()) {
            return null;
        }

        return (T)array[head];
    }

    public int size() {
        return (tail + length - head) % length;
    }

    public boolean isFull() {
        return (tail + 1) % length == head;
    }

    public boolean isEmpty() {
        return head == tail;
    }

    @Override
    public String toString() {
        if (isEmpty()) {
            return "[]";
        }

        StringBuilder sBuilder = new StringBuilder("[");
        for (int i = head, size = i + size(); i < size; i++) {
            sBuilder.append(array[i % length]);
            if (i != size - 1) {
                sBuilder.append(',').append(' ');
            }
        }
        sBuilder.append(']');
        return sBuilder.toString();
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章