基本定義:
int[] arr 是定義一個整型數組當隊列
maxSize是數組的最大容量
(這里規定,滿隊列時元素的個數是maxSize-1)
front指向隊列的第一個元素,也就是說 array[front] 是隊列的第一個元素
rear指向隊列的最后一個元素,初值為0
隊列滿的條件:(rear + 1) % maxSize == front
隊列為空的條件: rear == front
代碼
package com.zzfan.queue; import java.util.*; public class CircleArrayQueue { public static void main(String[] args) { System.out.println("測試數組環形隊列"); //創建一個環形隊列 CircleArray queue = new CircleArray(4); //隊列有效數據最大是3 char key = ' '; //接收用戶輸入 Scanner scanner = new Scanner(System.in); boolean loop = true; //輸出菜單 while (loop) { 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': queue.showQueue(); break; case 'a': System.out.println("輸出一個數"); int value = scanner.nextInt(); queue.addQueue(value); break; case 'g': try { int result = queue.getQueue(); System.out.printf("取出的數據是%d\n", result); } catch (Exception e) { System.out.println(e.getMessage()); } break; case 'h': try { int result = queue.headQueue(); System.out.printf("頭部的數據是%d\n", result); } catch (Exception e) { System.out.println(e.getMessage()); } break; case 'e': scanner.close(); loop = false; break; default: break; } } System.out.println("程序退出"); } } class CircleArray { //數組的最大容量 private int maxSize; //front指向隊列的第一個元素,也就是說arr[front]是隊列的第一個元素 private int front; //rear指向隊列的最后一個元素的最后一個位置,初值為0 private int rear; private int[] arr; //該數據用於存放數據,模擬隊列 public CircleArray(int arrMaxSize) { maxSize = arrMaxSize; arr = new int[maxSize]; } //判斷是否滿 public boolean isFull() { return (rear + 1) % maxSize == front; } //判斷是否為空 public boolean isEmpty() { return rear == front; } //添加數據到隊列 public void addQueue(int n) { //判斷隊列是否已滿 if (isFull()) { System.out.println("隊列已滿"); return; } //直接將數據加入 arr[rear] = n; //將rear后移,必須考慮取模 rear = (rear + 1) % maxSize; /* 這里手算了一下,實際取模就是想辦法當rear和隊列最大容量相等時,在加1就重新取到rear=1 有個通俗易懂的例子:跑步套圈 有一個環形跑道,假設,將環形跑道分割成10份。 front某時刻跑到第3格了,rear此時刻已經跑到第10格了。 那么rear繼續往下跑的時候,會發現,跑的第“11格”(實際並不存在)其實就是第1格,是第二圈的第1格。 */ } //獲取隊列的中的數據 public int getQueue() { //判斷隊列是否空 if (isEmpty()) { //通過拋出異常來處理 throw new RuntimeException("隊列為空,無法取出數據"); //throw可以直接return一個異常,不用再寫return } //front指向隊列的第一個元素 /* 1. 先把front對應的值保留到一個臨時變量中 2. front后移,考慮取模 3. 將臨時保存的變量返回 */ int value = arr[front]; //先獲取數據,front再后移 front = (front + 1) % maxSize; return value; } //顯示隊列的所有數據 public void showQueue() { //遍歷數組 if (isEmpty()) { System.out.println("隊列為空,沒有數據"); return; } //從front開始遍歷,對需要遍歷元素的個數進行計算。 for (int i = front; i < front + size(); i++) { System.out.printf("arr[%d] = %d\n", i % maxSize, arr[i % maxSize]); } } //有效數據的個數 public int size() { return (rear + maxSize - front) % maxSize; /*添加數據變的是rear,取出數據變的是front,所以當在第一個位置插入數據時,rear=2,front=1。 所以,如果不考慮取模,那有效數據個數就是rear-front 考慮取模的話會出現一種情況,rear已經開始“跑第二圈”了,front還在“第一圈” */ } //顯示隊列頭 public int headQueue() { //判斷是否為空 if (isEmpty()) { throw new RuntimeException("隊列為空,沒有數據"); } return arr[front]; } }
(防止忘記,盡量將注釋寫的多了些,記得看注釋)