數據結構---隊列及簡單實現有界隊列


隊列也是一種特殊的線性表,它只允許在兩端進行操作,插入或者取出,不允許操作中間的數據。比如只允許在對頭出隊,隊尾入隊。這樣就具有先進先出的特性(first in first out-FIFO)。就像排隊買東西一樣,不允許插隊,先排先買。

隊列分為單向隊列(有序隊列),就是上面所說的排隊模型,先進先出的操作,只允許一邊進,另一邊出,比如Java中的Queue。另外一種就是雙端隊列,兩端都可以進行進出操作。比如java中的Deque

既然隊列也是線性表的一種,那么實現隊列,就可以用數組或者鏈表來實現。

如果再細分一點的話,可以看着這倆接口的實現,簡單列舉幾個:

PriorityQueue數組實現的有序隊列,可以傳入一個比較器Comparator實現隊列中元素的順序。。

ArrayDeque:數組實現的雙端隊列

LinkedList:用鏈表實現的雙端隊列

Juc並發包下面:

ArrayBlockingQueue:數組實現的阻塞隊列

PriorityBlockingQueue:帶優先級的阻塞隊列

LinkedBlockingQueue:鏈表實現的阻塞隊列

可以看出大佬們的命名是很規范的,從類名直接可以看出來這隊列的特性以及用什么數據結構實現的。

 

簡單用數組實現一個有界隊列

 

1.初始化一個數組,這個是頭尾都是指向的0

 

 

 

2.插入三個元素,尾移動三位,指向了3

 

 

 3.取出一個元素,頭移動一位指向了1

 

 

 我們會發現頭指針走過的數組元素其實是空出來了的(index = 0)。假設尾指針走到最后了,但是因為我們有取出元素,前面有空位,所以按理來說,我們還可以繼續加入元素進去,但是這個時候怎么指針怎么回去呢?可以重新創建一個數組繼續開始,這樣的話會重新開辟內存空間,而且還需要將現有的數據復制到新的數組中去。如果我們只想讓這個隊列保持初始化大小,沒有擴容操作,創建一個新的數組去繼續放,從空間和時間復雜度來說都不合適了。這個時候我們可以通過取模操作,讓指針回去,從頭開始,既不用開辟新空間,也不用移動數據。這樣的話就需要考慮空隊列和滿隊這兩個狀態的判斷。如果滿了就無法插入,新數據直接丟棄,按如上邏輯實現一個簡單隊列。

 

package com.nijunyang.algorithm.queue;

/**
 * Description:
 * Created by nijunyang on 2020/4/4 21:44
 */
public class MyQueue<E> {
    private static final int DEFAULT_SIZE = 10;
    private Object[] elements;
    private int headIndex;
    private int tailIndex;
    private int capacity; //從容量
    private int size;  //已放元素個數

    public MyQueue() {
        this(DEFAULT_SIZE);
    }

    public MyQueue(int capacity) {
        this.elements = new Object[capacity];
        this.capacity = capacity;

    }

    public void push(E e){
        if (isFull()) {  //插入先判斷是否滿
            return;
        }
        elements[tailIndex] = e;
        size++;
        tailIndex = (tailIndex + 1) % capacity;  //取模實現循環的操作
    }

    public E pop(){
        if(isEmpty()) {  //取元素先判空
            return null;
        }
        E e = (E) elements[headIndex];
        headIndex = (headIndex + 1) % capacity; //取模實現循環的操作
        size--;
        return e;
    }

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

    public int size(){
        return this.size;
    }

    public int getCapacity(){
        return this.capacity;
    }

    public boolean isFull(){
        return this.size == this.capacity;
    }

    public static void main(String[] args) {
        MyQueue<Integer> myQueue = new MyQueue(3);
        myQueue.push(1);
        System.out.println(myQueue.size());
        myQueue.push(2);
        myQueue.push(3);
        System.out.println(myQueue.pop());
        System.out.println(myQueue.size());
        myQueue.push(4);
        myQueue.push(5);
        System.out.println(myQueue.size());

    }


}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM