定義 隊列是一個有序列表,可以用數組或是鏈表來實現。 遵循先入先出的原則。即:先存入隊列的數據,要先取出。後存入的要後取出 模擬思路 隊列本身是有序列表,若使用數組的結構來存儲隊列的數據,則隊列數組的聲明如下圖, 其中 maxSize 是該隊列的最大容量 因為隊列的輸出、輸入是分別從前後端來處理,因 ...
定義
- 隊列是一個有序列表,可以用數組或是鏈表來實現。
- 遵循先入先出的原則。即:先存入隊列的數據,要先取出。後存入的要後取出
模擬思路
-
隊列本身是有序列表,若使用數組的結構來存儲隊列的數據,則隊列數組的聲明如下圖, 其中 maxSize 是該隊列的最大容量
-
因為隊列的輸出、輸入是分別從前後端來處理,因此需要兩個變數 front及 rear分別記錄隊列前後端的下標,front 會隨著數據輸出而改變,而 rear則是隨著數據輸入而改變,如圖所示
入隊出隊操作模擬
當我們將數據存入隊列時稱為”addQueue”,addQueue 的處理需要有兩個步驟:
-
將尾指針往後移:rear+1 , 當 front == rear 時,隊列為空
-
若尾指針 rear 小於隊列的最大下標 maxSize-1,則將數據存入 rear所指的數組元素中,否則無法存入數據。rear == maxSize - 1時,隊列滿
註意:front指向的是隊列首元素的前一個位置
實現代碼
import java.util.Scanner; public class ArrayQueueDemo { public static void main(String[] args) { ArrayQueue queue = new ArrayQueue(3); Scanner scanner = new Scanner(System.in); boolean flag = true; while (flag){ System.out.println("輸入a(add)添加數據"); System.out.println("輸入g(get)取出數據"); System.out.println("輸入s(show)顯示所有數據"); System.out.println("輸入h(head)顯示頭部數據"); System.out.println("輸入e(exit)退出程式"); char c = scanner.next().charAt(0); switch (c){ case 'a': System.out.println("請輸入數據"); int num = scanner.nextInt(); queue.addNum(num); break; case 'g': try { queue.getQueue(); System.out.println("取出成功"); }catch (Exception e){ System.out.println(e.getMessage()); } break; case 's': queue.showQueue(); break; case 'h': try { queue.headQueue(); }catch (Exception e){ System.out.println(e.getMessage()); } break; case 'e': flag = false; System.out.println("程式已退出"); break; default: break; } } scanner.close(); } } class ArrayQueue{ private int maxSize;//隊列的大小 private int front;//指向隊列首元素的前一個位置 private int rear;//指向隊列的尾元素 private int[] arr;//用數組來實現隊列 //構造方法初始化 public ArrayQueue(int maxSize) { this.maxSize = maxSize; front = -1;//指向的是隊列第一個元素的前一個位置 rear = -1; arr = new int[maxSize]; } /** * 判斷隊列是否裝滿 * @return */ public boolean isFull(){ return rear == maxSize-1; } /** * 判斷隊列是否為空 * @return */ public boolean isEmpty(){ return front == rear; } /** * 為隊列添加數據 * @param num */ public void addNum(int num){ if (isFull()){ System.out.println("隊列已經滿了,無法再加入數據"); return; } rear++; arr[rear] = num; } /** * 取出隊列中的數據 * @return */ public int getQueue(){ if (isEmpty()){ throw new RuntimeException("隊列為空,不能取出數據"); } front++; return arr[front]=0; } /** * 顯示隊列的所有數據 */ public void showQueue(){ if (isEmpty()) { System.out.println("隊列為空,沒有數據"); return; } for (int i = 0; i<arr.length; i++){ System.out.printf("arr[%d]=%d\n",i,arr[i]); } } /** * 顯示隊列的頭數據,註意不是取出數據 * @return */ public int headQueue(){ if (isEmpty()){ throw new RuntimeException("隊列為空,沒有數據"); } return arr[front+1]; } }
運行結果
註意:因先入先出的原則,front和rear最終都會在隊列頂部,所以上述隊列只能一次性使用,沒有達到復用的效果,因此我們要用到環形隊列
環形隊列
思路:
- front變數含義調整:front變數指向隊首元素,初值為0
- rear變數含義調整:rear變數指向隊尾元素的下一個元素,初值為0。規定空出一個位置
- 隊列為空的判定條件:front == rear
- 隊列為滿的判定條件:(rear + 1) % maxSize == front
- 隊列中有效元素的個數:(rear - front + maxSize) % maxSize
- 入隊和出隊時,都需要讓標記對maxSize取模
-
import java.util.Scanner; public class CyclicArrayQueueDemo { public static void main(String[] args) { CyclicArrayQueue queue = new CyclicArrayQueue(3); Scanner scanner = new Scanner(System.in); boolean flag = true; while (flag){ System.out.println("輸入a(add)添加數據"); System.out.println("輸入g(get)取出數據"); System.out.println("輸入s(show)顯示所有數據"); System.out.println("輸入h(head)顯示頭部數據"); System.out.println("輸入e(exit)退出程式"); char c = scanner.next().charAt(0); switch (c){ case 'a': System.out.println("請輸入數據"); int num = scanner.nextInt(); queue.addNum(num); break; case 'g': try { int n = queue.getQueue(); System.out.println("取出的數是:"+n); }catch (Exception e){ System.out.println(e.getMessage()); } break; case 's': queue.showQueue(); break; case 'h': try { queue.headQueue(); }catch (Exception e){ System.out.println(e.getMessage()); } break; case 'e': flag = false; System.out.println("程式已退出"); break; default: break; } } scanner.close(); } } class CyclicArrayQueue { private int maxSize;//隊列的大小 private int front;//front變數指向隊首元素,初值為0 private int rear;//rear變數指向隊尾元素的下一個元素,初值為0。規定空出一個位置 private int[] arr;//用數組來實現隊列 public CyclicArrayQueue(int maxSize) { this.maxSize = maxSize; arr = new int[maxSize]; } /** * 判斷隊列是否裝滿 * * @return */ public boolean isFull() { return (rear + 1) % maxSize == front; } /** * 判斷隊列是否為空 * * @return */ public boolean isEmpty() { return front == rear; } /** * 為隊列添加數據 * * @param num */ public void addNum(int num) { if (isFull()) { System.out.println("隊列已經滿了,無法再加入數據"); return; } arr[rear] = num; rear = (rear + 1) % maxSize; } /** * 取出隊列中的數據 * * @return */ public int getQueue() { if (isEmpty()) { throw new RuntimeException("隊列為空,不能取出數據"); } int value = arr[front]; front = (front + 1) % maxSize; return value; } /** * 顯示隊列的所有數據 */ public void showQueue() { if (isEmpty()) { System.out.println("隊列為空,沒有數據"); return; } 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; } /** * 顯示隊列的頭數據,註意不是取出數據 * @return */ public int headQueue(){ if (isEmpty()){ throw new RuntimeException("隊列為空,沒有數據"); } return arr[front]; } }
import
java.util.Scanner;
public
class
ArrayQueueDemo {
public
static
void
main(String[] args) {
ArrayQueue queue =
new
ArrayQueue(
3
);
Scanner scanner =
new
Scanner(System.in);
boolean
flag =
true
;
while
(flag){
System.out.println(
"輸入a(add)添加數據"
);
System.out.println(
"輸入g(get)取出數據"
);
System.out.println(
"輸入s(show)顯示所有數據"
);
System.out.println(
"輸入h(head)顯示頭部數據"
);
System.out.println(
"輸入e(exit)退出程式"
);
char
c = scanner.next().charAt(
0
);
switch
(c){
case
'a'
:
System.out.println(
"請輸入數據"
);
int
num = scanner.nextInt();
queue.addNum(num);
break
;
case
'g'
:
try
{
queue.getQueue();
System.out.println(