數據結構:單向隊列

一.什麼是隊列?

隊列(Queue)(Stack)一樣是一種線性數據結構,但是不同於棧的先入後出,隊列中的元素只能先入先出(First In First Out, 簡稱 FIFO),也就是元素只能從一端進,另一端出。隊列
通常,隊列的出口端叫做 隊頭(front),入口端叫做 隊尾(rear);數據元素進入隊列的過程就叫做 入隊,出隊列的過程就叫做 出隊。隊列中數據元素的進出要遵從 “先進先出”的原則。

二.隊列的實現

隊列的實現有以下兩種方式:

  • 順序隊列:數組來實現的隊列結構。
  • 鏈式隊列:用鏈表來實現的隊列結構。

三.隊列的應用

  • 實際生活中比較常見的,每次排隊在奶茶店買奶茶都應該是一個隊列。畢竟在前面的肯定先買到。
  • 在大學裏,如果所有的電腦終端都被佔用了,並且由於資源是有限的,學生們必須在一個等待表上簽字,在終端上登陸時間最長的學生將會首先被強制離開,而等待時間最長的學生將是下一個被允許使用電腦的用戶。

四.數組實現單向隊列

因爲隊列的進隊和出隊是分別從隊頭和隊尾來進行的,所以需要兩個變量 frontrear 分別記錄隊列隊頭和隊尾的下標,front 會隨着數據出隊而改變,而 rear 則是隨着數據入隊而改變。

1.入隊

  • 當數據存入隊列時,稱爲 " 入隊(addQueue) ";入隊 尾指針需要向後移,即: rear + 1。
  • 這裏要注意,當隊列已經是滿的時候,是無法入隊的,即:若隊尾指針 rear 小於 隊列的最大下標 - 1,則將數據存入 rear 所指的數組元素中,否則無法存入數據。

2.出隊

  • 當數據出隊時,出隊 頭指針需要向後移,即:front + 1。

五.特殊情況處理

  • 隊列爲空,即 front == rear
// 判斷隊列是否爲空
    public boolean isEmptyQueue() {
        return rear == front;
    }

隊列是否已滿,當尾指針等於隊列最大下標 - 1時判斷爲滿,即:rear == maxSize - 1

// 判斷隊列是否已滿
    public boolean ifFullQueue() {
        return rear == maxSize - 1;
    }

六.代碼

import java.util.Queue;
import java.util.Scanner;
import javax.management.RuntimeOperationsException;

public class ArrayQueueDemo {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        ArrayQueue arrayQueue = new ArrayQueue(5);  // 隊列長度設置 5
        char input = ' '; // 用戶輸入
        boolean loop = true;
        // 菜單
        while (loop) {
            System.out.println("s(showQueue): 打印隊列");
            System.out.println("a(addQueue): 添加數據-入隊");
            System.out.println("g(getQueue): 取出數據-出隊");
            System.out.println("h(showFront): 查看隊頭的數據");
            System.out.println("e(exit): 退出程序");
            // 獲取用戶輸入的字符
            input = scanner.next().charAt(0);

            switch (input) {
                case 's':
                    arrayQueue.showQueue();
                    break;
                case 'a':
                    System.out.println("輸入一個數");
                    int value = scanner.nextInt();
                    arrayQueue.addQueue(value);
                    break;
                case 'g':
                    try {
                        int res = arrayQueue.getQueue();
                        System.out.printf("取出的數據爲: %d\n", res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'h':
                    try {
                        int res = arrayQueue.showHeadQueue();
                        System.out.printf("隊列頭的數據是: %d\n", res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e':
                    scanner.close();
                    loop = false;
                    break;
                default: 
                    break;
            }
        }

        System.out.println("程序退出!");
    }
}

// 用數組實現隊列,先創建一個 ArrayQueue類
class ArrayQueue {
    private int maxSize;    // 數組的最大容量
    private int front;      // 隊列頭部
    private int rear;       // 隊列尾部
    private int[] arr;      // 數組模擬隊列,存放數據

    // 創建隊列的有參構造器
    public ArrayQueue(int arrMaxSize) {
        maxSize = arrMaxSize;
        arr = new int[maxSize];
        front = -1;         // 默認指向隊列頭部的前一個位置
        rear = -1;          // 指向隊尾的數據(隊列的最後一個數據)
    }

    // 判斷隊列是否已滿
    public boolean ifFullQueue() {
        return rear == maxSize - 1;
    }

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

    public void addQueue(int n) {
        // 先判斷隊列是否已經滿
        if (ifFullQueue()) {
            System.out.println("隊列已經滿了,不能繼續添加數據");
            return;
        }
        rear++;
        arr[rear] = n;
    }

    // 出隊
    public int getQueue() {
        // 先判斷隊列是否爲空
        if (isEmptyQueue()) {
            // 拋出異常
            throw new RuntimeException("隊列爲空, 不能獲取數據");
        }
        front++;
        return arr[front];
    }

    public void showQueue() {
        // 遍歷隊列
        // 以及判斷是否爲空
        if (isEmptyQueue()) {
            // 拋出異常
            System.out.println("隊列爲空,不能獲取數據");
            return;
        }

        for (int i = 0; i < arr.length; i++) {
            System.out.printf("arr[%d] = %d\n", i, arr[i]);
        }
    }

    // 顯示隊頭數據元素
    public int showHeadQueue() {
        // 先判斷隊列是否爲空
        if (isEmptyQueue()) {
            // 拋出異常
            throw new RuntimeException("隊列爲空,不能獲取數據");
        }
        return arr[front + 1];
    } 

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