1. 程式人生 > 實用技巧 >java資料結構與演算法二: 佇列(陣列模擬佇列)

java資料結構與演算法二: 佇列(陣列模擬佇列)

佇列:陣列模擬佇列

一、佇列介紹

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

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

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

二、陣列模擬佇列思路

1)佇列本身是有序列表,若使用陣列的結構來儲存佇列的資料,則佇列陣列的宣告如下圖,其中maxSize是該佇列的最大容量。

2)因為佇列的輸出、輸入是分別從前後端來處理,因此需要兩個變數front及rear分別記錄佇列前後端的下標,front會隨著資料輸出而改變,而rear則是隨著資料輸入而改變,如下圖:

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

​ 1)將尾指標往後移:rear + 1,當front == rear,則佇列為空

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

三、程式碼實現

public class ArrayQueueDemo {
	
	public static void main(String[] args) {
		//測試
		//建立一個佇列
		ArrayQueue arrayQueue = 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':	//顯示佇列
				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) {
					// TODO: handle exception
					System.out.println(e.getMessage());
				}
				break;
			case 'h':	//檢視佇列頭的資料
				try {
					int res = arrayQueue.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) {
		super();
		this.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];
	}
}