05.Java數據結構與算法之~隊列與環形隊列CircleArrayQueue

05.Java數據結構與算法之~隊列與環形隊列CircleArrayQueue

隊列的介紹

.

       隊列(queue)是隻允許在一端進行插入操作,而在另一端進行刪除操作的線性表

       插入的一端稱爲隊尾,刪除的一端稱爲隊頭

       隊列是一個有序列表,可以用數組或是鏈表實現

隊列的缺點:

       出隊複雜度高 O(n),容易假溢出

隊列的鏈式存儲及結構模式

       隊列的鏈式存儲結構,其實就是線性表的單鏈表,只不過它只能從尾進,從頭出而已。

空隊列->>

數組模擬隊列

創建Queue接口
public interface Queue{
    boolean isFull();
    boolean isEmpty();
    void add(Object n);
    Object get();
    String toString();
    Object Head();
    int size();
}
數組模擬隊列代碼實現
//使用數組模擬隊列,編寫一個ArrayQueued類
public class ArrayQueue implements Queue{
    private int maxSize;                //表示數組的最大容量
    private int front;                  //隊列頭
    private int rear;                   //隊列尾
    private Object[]arr;                //存放數據
    private int size;  //隊列的大小,如果初始值是16,用戶沒填滿,遍歷時防止出現NULL
    private final int INITIAL=16;       //初始大小爲16

    //創建隊列的構造器
    public ArrayQueue(int arrMaxSize){
        maxSize = arrMaxSize;
        arr = new Object[maxSize];
        front = -1; //面向隊列頭部,指向隊列頭的前一個位置
        rear = -1;  //面向隊列尾
    }

    //如果用戶沒設置大小,則默認爲初始大小
    public ArrayQueue(){
        maxSize = INITIAL;
        arr = new Object[INITIAL];
        front = -1;
        rear = -1;
    }
    
    //判斷隊列是否已滿
    public boolean isFull(){
        return rear == maxSize-1;
    }

    //判斷隊列是否爲空
    @Override
    public boolean isEmpty(){
        return front == rear;
    }

    //添加數據到隊列
    @Override
    public void add(Object n){
        if(isFull()){
            throw new IndexOutOfBoundsException("隊列滿!");
        }
        rear++; //讓rear後移
        size++; //讓大小增加
        arr[rear] = n;
    }
    //返回隊列長度
     @Override
    public int size(){
        return size - (front + 1);
    }
    
    //獲取隊列數據,出隊列
    @Override
    public Object get(){
        //判斷隊列是否空
        if(isEmpty()){
            throw new NullPointerException("隊列爲空!");
        }
        front++;    //讓front後移
        return arr[front];
    }
    //遍歷隊列
    @Override
    public String toString(){
        if(isEmpty()){
            throw new NullPointerException("隊列爲空!");
        }
        StringBuilder stringBuilder = new StringBuilder("[");
        //循環到隊列的倒數第二個位置結束循環,防止多加一個逗號妨礙美觀
        for(int i = front + 1; i < size - 1; i++){
            stringBuilder.append(arr[i] + ",");
        }
        //添加最後一個數據
        stringBuilder.append(arr[size-1] + "]");
        return stringBuilder.toString();
    }
    //返回頭數據
    @Override
    public Object Head(){
        //判斷是否爲空
        if(isEmpty()){
            throw new NullPointerException("隊列空!");
        }
        return arr[front+1];
    }
}

環形數組隊列模擬

把隊列的這種頭尾相接的順序存儲結構稱爲循環隊列

       變量的含義做一個調整:front指向第一個元素,rear指向最後一個元素

隊列的構造器
    //由於front和rear默認爲0,所以不需要賦值了
    public CircleArrayQueue(int arrMaxSize){
        maxSize = arrMaxSize;
        arr = new Object[maxSize];
    }
判斷隊列是否已滿
    public boolean isFull(){
        return (rear + 1) % maxSize == front;
    }
添加數據到隊列
    @Override
    public void add(Object n){
        if(isFull()){
            throw new IndexOutOfBoundsException("隊列滿!");
        }
        arr[rear] = n;
        //將rear後移
        rear = (rear + 1) % maxSize;
    }
獲取隊列數據,出隊列

       先把front對應的值保存到一個臨時變量,將front後移,返回臨時變量

  public Object get(){
        //判斷隊列是否空
        if(isEmpty()){
            throw new NullPointerException("隊列爲空!");
        }
        Object value = arr[front];
        front = (front + 1) % maxSize;
        return value;
    }
求長
    public int size(){
        return (rear + maxSize - front) % maxSize;
    }

代碼實現

public class CircleArrayQueue implements Queue{
    private int maxSize;                //表示數組的最大容量
    private int front;                  //隊列頭
    private int rear;                   //隊列尾
    private Object[]arr;                //存放數據
    private final int INITIAL=16;       //初始大小爲16

    //創建隊列的構造器
    public CircleArrayQueue(int arrMaxSize){
        maxSize = arrMaxSize;
        arr = new Object[maxSize];
    }

    //如果用戶沒設置大小,則默認爲初始大小
    public CircleArrayQueue(){
        maxSize = INITIAL;
        arr = new Object[INITIAL];
    }

    //判斷隊列是否已滿
    public boolean isFull(){
        return (rear + 1) % maxSize == front;
    }

    //判斷隊列是否爲空
    @Override
    public boolean isEmpty(){
        return front == rear;
    }

    //添加數據到隊列
    @Override
    public void add(Object n){
        if(isFull()){
            throw new IndexOutOfBoundsException("隊列滿!");
        }
        arr[rear] = n;
        //將rear後移
        rear = (rear + 1) % maxSize;
    }

    //獲取隊列數據,出隊列
    @Override
    public Object get(){
        //判斷隊列是否空
        if(isEmpty()){
            throw new NullPointerException("隊列爲空!");
        }
        Object value = arr[front];
        front = (front + 1) % maxSize;
        return value;
    }
    //隊列長度
    @Override
    public int size(){
        return (rear + maxSize - front) % maxSize;
    }

    //遍歷隊列
    @Override
    public String toString(){
        if(isEmpty()){
            throw new NullPointerException("隊列爲空!");
        }
        StringBuilder stringBuilder = new StringBuilder("[");
        //循環到隊列的倒數第二個位置結束循環,防止多加一個逗號妨礙美觀
        for(int i = front ; i < rear - 1; i++){
            stringBuilder.append(arr[i] + ",");
        }
        //添加最後一個數據
        stringBuilder.append(arr[rear-1] + "]");
        return stringBuilder.toString();
    }
    //返回頭數據
    @Override
    public Object Head(){
        //判斷是否爲空
        if(isEmpty()){
            throw new NullPointerException("隊列空!");
        }
        return arr[front];
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章