1. 程式人生 > 遊戲 >黑客做好事?《戰區》主播的賬號被升到1000級解鎖全武器及迷彩

黑客做好事?《戰區》主播的賬號被升到1000級解鎖全武器及迷彩

佇列介紹

1) 佇列是一個有序列表,可以用陣列或是連結串列來實現。

2) 遵循先入先出的原則。即:先存入佇列的資料,要先取出。後存入的要後取

3) 示意圖:(使用陣列模擬佇列示意圖)

佇列本身是有序列表,若使用陣列的結構來儲存佇列的資料,則佇列陣列的宣告如下圖, 其中 maxSize 是該隊

列的最大容量。

因為佇列的輸出、輸入是分別從前後端來處理,因此需要兩個變數 front 及 rear 分別記錄佇列前後端的下標,

front 會隨著資料輸出而改變,而 rear 則是隨著資料輸入而改變,如圖所示:

當我們將資料存入佇列時稱為”addQueue”,addQueue 的處理需要有兩個步驟:思路分析

1) 將尾指標往後移:rear+1 , 當 front == rear 【空】

2) 若尾指標 rear 小於佇列的最大下標 maxSize-1,則將資料存入 rear 所指的陣列元素中,否則無法存入資料。

rear == maxSize - 1[佇列滿]

程式碼實現

點選檢視程式碼


import java.util.Scanner;

public class ArrayQueueDemo {

	public static void main(String[] args) {
		//測試一把
		//建立一個佇列
		ArrayQueue queue = new ArrayQueue(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 res = queue.getQueue();
					System.out.printf("取出的資料是%d\n", res);
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println(e.getMessage());
				}
				break;
			case 'h': //檢視佇列頭的資料
				try {
					int res = queue.headQueue();
					System.out.printf("佇列頭的資料是%d\n", res);
				} catch (Exception e) {
					// TODO: handle exception
					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; // 指向佇列頭部,分析出front是指向佇列頭的前一個位置.
		rear = -1; // 指向佇列尾,指向佇列尾的資料(即就是佇列最後一個數據)
	}

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

	// 判斷佇列是否為空
	public boolean isEmpty() {
		return rear == front;
	}

	// 新增資料到佇列
	public void addQueue(int n) {
		// 判斷佇列是否滿
		if (isFull()) {
			System.out.println("佇列滿,不能加入資料~");
			return;
		}
		rear++; // 讓rear 後移
		arr[rear] = n;
	}

	// 獲取佇列的資料, 出佇列
	public int getQueue() {
		// 判斷佇列是否空
		if (isEmpty()) {
			// 通過丟擲異常
			throw new RuntimeException("佇列空,不能取資料");
		}
		front++; // front後移
		return arr[front];

	}

	// 顯示佇列的所有資料
	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]);
		}
	}

	// 顯示佇列的頭資料, 注意不是取出資料
	public int headQueue() {
		// 判斷
		if (isEmpty()) {
			throw new RuntimeException("佇列空的,沒有資料~~");
		}
		return arr[front + 1];
	}
}

問題分析並優化

1) 目前陣列使用一次就不能用, 沒有達到複用的效果

2) 將這個陣列使用演算法,改進成一個環形的佇列 取模:%

陣列模擬環形佇列

對前面的陣列模擬佇列的優化,充分利用陣列. 因此將陣列看做是一個環形的。(通過取模的方式來實現即可)

1) 尾索引的下一個為頭索引時表示佇列滿,即將佇列容量空出一個作為約定,這個在做判斷佇列滿的

時候需要注意 (rear + 1) % maxSize == front 滿]

2) rear == front [空]

3) 分析示意圖:

程式碼實現

點選檢視程式碼

import java.util.Scanner;

public class ArrayQueueDemo {

	public static void main(String[] args) {
		//測試一把
		//建立一個佇列
		ArrayQueue queue = new ArrayQueue(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 res = queue.getQueue();
					System.out.printf("取出的資料是%d\n", res);
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println(e.getMessage());
				}
				break;
			case 'h': //檢視佇列頭的資料
				try {
					int res = queue.headQueue();
					System.out.printf("佇列頭的資料是%d\n", res);
				} catch (Exception e) {
					// TODO: handle exception
					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; // 指向佇列頭部,分析出front是指向佇列頭的前一個位置.
		rear = -1; // 指向佇列尾,指向佇列尾的資料(即就是佇列最後一個數據)
	}

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

	// 判斷佇列是否為空
	public boolean isEmpty() {
		return rear == front;
	}

	// 新增資料到佇列
	public void addQueue(int n) {
		// 判斷佇列是否滿
		if (isFull()) {
			System.out.println("佇列滿,不能加入資料~");
			return;
		}
		rear++; // 讓rear 後移
		arr[rear] = n;
	}

	// 獲取佇列的資料, 出佇列
	public int getQueue() {
		// 判斷佇列是否空
		if (isEmpty()) {
			// 通過丟擲異常
			throw new RuntimeException("佇列空,不能取資料");
		}
		front++; // front後移
		return arr[front];

	}

	// 顯示佇列的所有資料
	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]);
		}
	}

	// 顯示佇列的頭資料, 注意不是取出資料
	public int headQueue() {
		// 判斷
		if (isEmpty()) {
			throw new RuntimeException("佇列空的,沒有資料~~");
		}
		return arr[front + 1];
	}
}