數組實現隊列:
一、實現普通隊列
1) 將尾指針往後移:rear+1 , 當 front == rear 【空】
2) 若尾指針 rear 小於隊列的最大下標 maxSize-1,則將數據存入 rear 所指的數組元素中,否則無法存入數據。rear == maxSize - 1[隊列滿]
public static void main(String[] args) {
ArrayCircleQueue mArrayQueueTest = new ArrayCircleQueue(5);
Scanner scanner = new Scanner(System.in);
char key = ' '; //接收用戶輸入
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':
mArrayQueueTest.showQueue();
break;
case 'a':
System.out.println("輸出一個數");
int value = scanner.nextInt();
mArrayQueueTest.addQueue(value);
break;
case 'g': //取出數據
try {
int res = mArrayQueueTest.getQueue();
System.out.printf("取出的數據是%d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'h': //查看隊列頭的數據
try {
int res = mArrayQueueTest.peek();
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;
}
}
}
/**
1. 數組實現單項隊列
2. 1) 將尾指針往後移:rear+1 , 當 front == rear 【空】
3. 2) 若尾指針 rear 小於隊列的最大下標 maxSize-1,則將數據存入 rear 所指的數組元素中,否則無法存入數據。
4. 3) 判斷隊列 滿沒滿 end == mMaxSize - 1
5. 頭指針在隊列的前一個位置。是這麼設計的(你也可以放在當前頭的位置)
*/
static class ArrayQueueTest{
// 頭指針
public int head = -1;
// 尾指針
public int end = -1;
// 隊列
public int[] mQueue;
// 隊列的最大容量
public int mMaxSize;
public ArrayQueueTest(int mMaxSize) {
this.mMaxSize = mMaxSize;
mQueue = new int[mMaxSize];
}
/**
* 添加數據
*/
public void addQueue(int data){
if(isFull()) {
System.out.print("隊列已經滿了");
return;
}
// 尾指針往後加
end++;
mQueue[end] = data;
}
/**
* 取數據
*/
public int getQueue(){
if(isEmpty()) {
throw new RuntimeException("隊列爲空哦~~~");
}
// 頭指針往後移
head++;
return mQueue[head];
}
/**
* 查看頭數據
*/
public int peek(){
if(isEmpty()) {
throw new RuntimeException("隊列爲空哦~~~");
}
return mQueue[head + 1];
}
/**
* 遍歷數組
*/
public void showQueue(){
if(isEmpty()) {
System.out.println("隊列空的,沒有數據~~");
return;
}
for(int i = 0; i < mQueue.length; i++) {
System.out.println(i+" ------> "+mQueue[i]);
}
}
/**
* 判斷隊列是否爲空
* @return
*/
public boolean isEmpty(){
return head == end;
}
/**
* 判斷隊列滿沒滿
*/
public boolean isFull(){
return end == mMaxSize - 1;
}
}
二、實現環形隊列
分析說明:
1、尾索引的下一個爲頭索引時表示隊列滿,即將隊列容量空出一個作爲約定,這個在做判斷隊列滿的時候需要注意 (rear + 1) %maxSize == front 滿]
2、 rear == front [空]
3、爲什麼要預留一個空間呢?因爲這樣比較好判斷是不是滿了,是不是空(若不使用空節點。當font-rear=-1時,不能判斷是空還是滿.這時可能會多一些處理語句。比如:在出隊列時,如果發現font=rear的情況。在出隊列以後將font=rear=-1.判斷爲空的唯一條件就是font=rear=-1)
4、分析示意圖:
public static void main(String[] args) {
ArrayCircleQueue mArrayQueueTest = new ArrayCircleQueue(5);
Scanner scanner = new Scanner(System.in);
char key = ' '; //接收用戶輸入
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':
mArrayQueueTest.showQueue();
break;
case 'a':
System.out.println("輸出一個數");
int value = scanner.nextInt();
mArrayQueueTest.addQueue(value);
break;
case 'g': //取出數據
try {
int res = mArrayQueueTest.getQueue();
System.out.printf("取出的數據是%d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'h': //查看隊列頭的數據
try {
int res = mArrayQueueTest.peek();
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;
}
}
}
/**
* 數組實現環形隊列
* *) 隊列尾部空餘一個空間
* 1)判斷隊列滿沒滿 (end + 1 )% size == head 尾指針+ 1(預留空間) % size == 頭指針說明數組滿了
* 2)判斷隊列有效個數 (end + size - head) % size
*/
static class ArrayCircleQueue{
// 頭指針
public int head;
// 尾指針
public int end;
// 隊列
public int[] mQueue;
// 隊列的最大容量
public int mMaxSize;
public ArrayCircleQueue(int mMaxSize) {
this.mMaxSize = mMaxSize;
mQueue = new int[mMaxSize];
}
/**
* 添加數據
*/
public void addQueue(int data){
if(isFull()) {
System.out.print("隊列已經滿了");
return;
}
mQueue[end] = data;
// 尾指針計算
end = (end + 1) % mMaxSize;
}
/**
* 取數據
*/
public int getQueue(){
if(isEmpty()) {
throw new RuntimeException("隊列爲空哦~~~");
}
// 頭指針往後移
int value = mQueue[head];
head = (head + 1) % mMaxSize;
return value;
}
/**
* 查看頭數據
*/
public int peek(){
if(isEmpty()) {
throw new RuntimeException("隊列爲空哦~~~");
}
return mQueue[head];
}
// 顯示隊列的所有數據
public void showQueue() {
// 遍歷
if (isEmpty()) {
System.out.println("隊列空的,沒有數據~~");
return;
}
// 思路:從front開始遍歷,遍歷多少個元素
for (int i = head; i < head + size() ; i++) {
System.out.printf("arr[%d]=%d\n", i % mMaxSize, mQueue[i % mMaxSize]);
}
}
// 求出當前隊列有效數據的個數
public int size() {
// rear = 2
// front = 1
// maxSize = 3
return (end + mMaxSize - head) % mMaxSize;
}
/**
* 判斷隊列是否爲空
* @return
*/
public boolean isEmpty(){
return head == end;
}
/**
* 判斷隊列滿沒滿
*/
public boolean isFull(){
return head == (end + 1) % mMaxSize;
}
}