好玩的數據結構與算法————數組實現隊列和循環隊列

隊列:

  1. 隊列是一個有序列表,可以用數組或是鏈表來實現。
  2. 遵循先入先出的原則。即:先存入隊列的數據,要先取出。後存入的要後取出
    單向隊列:
    在這裏插入圖片描述
    front:指向隊列頭部,front是指向隊列頭部的前一個位置
    rear:指向隊列尾的數據
    當我們將數據存入隊列時稱爲”addQueue”,addQueue 的處理需要有兩個步驟:思路分析
  1. 將尾指針往後移:rear+1 , 當 front == rear 【空】
  2. 若尾指針 rear 小於隊列的最大下標 maxSize-1,則將數據存入 rear 所指的數組元素中,否則無法存入數據。
    rear == maxSize - 1[隊列滿]

單向隊列實現

public class ArrayQueue {

    /**
     * 隊列頭
     */
    private int front;

    /**
     * 隊列尾
     */
    private int rear;

    /**
     * 數組最大容量
     */
    private int maxsize;

    /**
     * 該數據用於存放數據,模擬隊列
     */
    private int [] arr;

    public int getFront() {
        return front;
    }

    public void setFront(int front) {
        this.front = front;
    }

    public int getRear() {
        return rear;
    }

    public void setRear(int rear) {
        this.rear = rear;
    }

    public int getMaxsize() {
        return maxsize;
    }

    public void setMaxsize(int maxsize) {
        this.maxsize = maxsize;
    }

    public int[] getArr() {
        return arr;
    }

    public void setArr(int[] arr) {
        this.arr = arr;
    }

    /**
     * @Description: ArrayQueue 隊列構造器
     * @param: [maxsize]
     * @return:
     * @auther: zqq
     * @date: 20/5/18 18:13
     */
    public ArrayQueue(int maxsize) {
        // 指向隊列頭部,front是指向隊列頭部的前一個位置
        this.front = -1;
        // 指向隊列尾的數據
        this.rear = -1;
        this.maxsize = maxsize;
        this.arr = new int[maxsize];
    }

    /**
     * @Description: isEmpty 判斷是否爲空
     * @param: []
     * @return: boolean
     * @auther: zqq
     * @date: 20/5/18 18:36
     */
    public boolean isEmpty(){
        return this.getFront() == this.getRear();
    }

    /**
     * @Description: isFull 判斷隊列是否已滿
     * @param: []
     * @return: boolean
     * @auther: zqq
     * @date: 20/5/18 18:36
     */
    public boolean isFull(){
        return this.getRear() == this.getMaxsize() -  1;
    }

    /**
     * @Description: addQueue 向隊列添加數據
     * @param: [n]
     * @return: void
     * @auther: zqq
     * @date: 20/5/18 18:21
     */
    public void addQueue(int n){
        if (isFull()){
            System.out.println("隊列已滿");
            return;
        }
        this.setRear(this.getRear()+1);
        this.arr[this.getRear()] = n;
    }

    /**
     * @Description: getQueue 出隊列
     * @param: []
     * @return: int
     * @auther: zqq
     * @date: 20/5/18 18:37
     */
    public int getQueue() throws Exception {
        if (isEmpty()){
            System.out.println("隊列爲空");
            throw new RuntimeException("隊列爲空");
        }
        this.setFront(this.getFront()+1);
        return this.getArr()[this.getFront()];
    }

    /**
     * @Description: showQueue 展示隊列
     * @param: []
     * @return: void
     * @auther: zqq
     * @date: 20/5/18 18:37
     */
    public void showQueue(){
        if (isEmpty()){
            System.out.println("隊列爲空");
            return;
        }
        for (int i = 0; i < this.getArr().length; i++) {
            System.out.printf("arr[%d] = %d\n", i, this.getArr()[i]);
        }
    }

    /**
     * @Description: headQueue 查看隊列頭部
     * @param: []
     * @return: int
     * @auther: zqq
     * @date: 20/5/18 18:37
     */
    public int headQueue(){
        if (isEmpty()){
            System.out.println("隊列爲空,沒有任何數據");
            throw new RuntimeException("對內爲空");
        }
        int i = this.getArr()[this.getFront()+1];
        return i;
    }
}

測試代碼

public class TestQueue {
    public static void main(String[] args) {
        ArrayQueue arrayQueue = new ArrayQueue(3);
        char key = ' ';
        Scanner scanner = new Scanner(System.in);
        boolean bool = true;
        while (bool){
            System.out.println("s(show):顯示隊列");
            System.out.println("e(exit):推出程序");
            System.out.println("a(add):添加數據到隊列");
            System.out.println("g(get):從對內取出數據");
            System.out.println("h(head):查看隊列頭的數據");
            key = scanner.next().charAt(0);
            switch (key){
                case 's':
                    arrayQueue.showQueue();
                    break;
                case 'a':
                    System.out.println("請輸入一個數");
                    int v = scanner.nextInt();
                    arrayQueue.addQueue(v);
                    break;
                case 'g':
                    try {
                        int queue = arrayQueue.getQueue();
                        System.out.printf("取出來的數據是 %d\n ", queue);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                case 'h':
                    try {
                        int queue = arrayQueue.headQueue();
                        System.out.printf("隊列頭數據是 %d\n ", queue);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                case 'e':
                    scanner.close();
                    bool = false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序退出~~~");
    }
}

循環隊列

單向隊列出隊之後有空間浪費,解決方法是讓隊列進行循環。
思路:
思路如下:

  1. front 變量的含義做一個調整: front 就指向隊列的第一個元素, 也就是說 arr[front] 就是隊列的第一個元素
    front 的初始值 = 0
  2. rear 變量的含義做一個調整:rear 指向隊列的最後一個元素的後一個位置. 因爲希望空出一個空間做爲約定.
    rear 的初始值 = 0
  3. 當隊列滿時,條件是 (rear + 1) % maxSize == front 【滿】
  4. 對隊列爲空的條件, rear == front 空
  5. 當我們這樣分析, 隊列中有效的數據的個數 (rear + maxSize - front) % maxSize // rear = 1 front = 0
  6. 我們就可以在原來的隊列上修改得到,一個環形隊列

代碼實現:

public class CircleArrayQueue {
    /**
     * 隊列頭
     */
    private int front;

    /**
     * 隊列尾
     */
    private int rear;

    /**
     * 數組最大容量
     */
    private int maxsize;

    /**
     * 該數據用於存放數據,模擬隊列
     */
    private int [] arr;

    public int getFront() {
        return front;
    }

    public void setFront(int front) {
        this.front = front;
    }

    public int getRear() {
        return rear;
    }

    public void setRear(int rear) {
        this.rear = rear;
    }

    public int getMaxsize() {
        return maxsize;
    }

    public void setMaxsize(int maxsize) {
        this.maxsize = maxsize;
    }

    public int[] getArr() {
        return arr;
    }

    public void setArr(int[] arr) {
        this.arr = arr;
    }

    /**
     * @Description: ArrayQueue 隊列構造器
     * @param: [maxsize]
     * @return:
     * @auther: zqq
     * @date: 20/5/18 18:13
     */
    public CircleArrayQueue(int maxsize) {
        // front 變量的含義做一個調整: front 就指向隊列的第一個元素, 也就是說 arr[front] 就是隊列的第一個元素
        this.front = 0;
        // rear 變量的含義做一個調整:rear 指向隊列的最後一個元素的後一個位置. 因爲希望空出一個空間做爲約定.
        this.rear = 0;
        this.maxsize = maxsize;
        this.arr = new int[maxsize];
    }

    /**
     * @Description: isEmpty 判斷是否爲空
     * @param: []
     * @return: boolean
     * @auther: zqq
     * @date: 20/5/18 18:36
     */
    public boolean isEmpty(){
        return this.getFront() == this.getRear();
    }


    /**
     * @Description: isFull 判斷隊列是否已滿
     * @param: []
     * @return: boolean
     * @auther: zqq
     * @date: 20/5/18 18:36
     */
    public boolean isFull(){
        return (this.getRear() +1) % this.getMaxsize() == this.getFront();
    }

    public void addQueue(int n){
        if (isFull()){
            System.out.println("隊列已滿");
            return;
        }
        this.getArr()[this.getRear()] = n;
        this.setRear((this.getRear()+1) % this.getMaxsize());
    }

    public int getQueue() throws Exception {
        if (isEmpty()){
            System.out.println("隊列爲空");
            throw new RuntimeException("隊列爲空");
        }
        int value = this.getArr()[this.getFront()];
        this.setFront(this.getFront()+1 % this.getMaxsize());
        return value;
    }

    public void showQueue(){
        if (isEmpty()){
            System.out.println("隊列爲空");
            return;
        }
        for (int i = this.getFront(); i < this.getFront()+size(); i++) {
            System.out.printf("arr[%d] = %d\n", i % (this.getMaxsize()-1), this.getArr()[i % (this.getMaxsize()-1)]);
        }
    }

    public int size(){
        return (this.getRear() + this.getMaxsize() - this.getFront()) % this.getMaxsize();
    }

    public int headQueue(){
        if (isEmpty()){
            System.out.println("隊列爲空,沒有任何數據");
            throw new RuntimeException("對內爲空");
        }
        int i = this.getArr()[this.getFront()];
        return i;
    }
}

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