完整代碼拉到最底下
一、介紹
隊列顧名思義就像我們生活中排隊一樣,先進先出。
如上圖所示,25、16、5、9依次在隊列中,按照順序拿出的數據也分別是25、26、5、9。
二、實現過程及思路
底層使用數組來實現,實現的功能有插入數據到隊尾、移除隊首數據、查看隊首數據、判斷隊列是否為空、判斷隊列是否存滿。
將隊列的元素存儲在數組的某個區間內,隊列在數組中是連續的,所以使用變量標記隊列在數組中的位置。
1、編寫類及屬性
我們可以使用elements變量標記隊列中元素的數量,使用front變量標記隊首元素在數組的索引,end變量標記隊尾元素在數組中的索引。
public class MyQueue {
private Object[] arr;//存放隊列元素的數組
private int elements;//隊列元素數量
private int front;//隊頭元素在數組中的索引
private int end;//隊尾元素在數組中的索引
public MyQueue() {
arr = new Object[10];
elements = 0;
front = 0;
end = -1;
}
public MyQueue(int maxSize) {
arr = new Object[maxSize];
elements = 0;
front = 0;
end = -1;
}
}
2、隊列是否為空
標記隊列元數量的變量 elements 為 0 即為空
public boolean isEmpty() {
return elements == 0;
}
3、隊列是否已經滿了
隊列元素個數與數組的長度相等即為滿
public boolean isFull() {
return elements == arr.length;
}
4、獲取隊頭元素
獲取數組中索引為 front
的元素
public Object peek() {
return arr[front];
}
5、移除隊首元素
每次都是移除數組中索引為 front
的元素,下一個元素就變成了隊首,即front+1
,隊列元素個數elements-1
。共有三種情況要考慮,如果隊列已經空了就無須做任何操作,如果已經是最后一個元素,直接將標記位置的變量重置即可,其他情況正常操作。
public Object remove() {
if (isEmpty()) {
throw new RuntimeException("隊列已經是空的,放心使用吧");
}
Object value = arr[front++];
//如果已經是最后一個元素了,將指針重置即可
if (elements == 1) {
end = -1;
front = 0;
elements = 0;
} else {
elements--;
}
return value;
}
6、插入
我們編寫一個持續可用的隊列,所以要考慮到以下情況。
(1)存儲隊列的數組滿了(隊列滿了),這個好理解,滿了就無法向隊尾加入元素了。
(2)因為隊列在數組中是連續的,如果隊列的元素在數組中最后,需要將元素從隊首到隊尾移到數組中第一位,也就是將后面的位置空出來(參考下圖)。
public void insert(Object value) {
//檢測隊列是否已經滿了
if (isFull()) {
throw new RuntimeException("隊列內元素已達到設定長度");
}
//如果后面沒有空位置,將余下元素放到數組的頭
if (elements > 1 && end == arr.length - 1) {
int i = 0;
for (; i < elements; i++, front++) {
arr[i] = arr[front];
}
front = 0;
end = i-1;
}
//其他情況正常向后添加元素
arr[++end] = value;
elements++;
}
7、測試
public static void main(String[] args) {
MyQueue queue = new MyQueue(4);
queue.insert(11);
queue.insert(12);
queue.insert(13);
queue.insert(14);
queue.remove();
queue.remove();
queue.insert(16);
//queue.remove();
//queue.remove();
//queue.insert(19);
//queue.insert(20);
queue.remove();
queue.remove();
queue.insert(21);
queue.insert(22);
while (!queue.isEmpty()) {
System.out.println(queue.remove());
}
}
三、完整代碼
package com.jikedaquan.datastruct;
public class MyQueue {
private Object[] arr;
private int elements;//隊列元素數量
private int front;//隊頭元素在數組中的索引
private int end;//隊尾元素在數組中的索引
public MyQueue() {
arr = new Object[10];
elements = 0;
front = 0;
end = -1;
}
public MyQueue(int maxSize) {
arr = new Object[maxSize];
elements = 0;
front = 0;
end = -1;
}
//從隊尾插入
public void insert(Object value) {
//檢測隊列是否已經滿了
if (isFull()) {
throw new RuntimeException("隊列內元素已達到設定長度");
}
//如果后面沒有空位置,將余下元素放到數組的頭
if (elements > 1 && end == arr.length - 1) {
int i = 0;
for (; i < elements; i++, front++) {
arr[i] = arr[front];
}
front = 0;
end = i-1;
}
arr[++end] = value;
elements++;
}
//刪除數據,從隊頭刪除
public Object remove() {
if (isEmpty()) {
throw new RuntimeException("隊列已經是空的,放心使用吧");
}
Object value = arr[front++];
//如果已經是最后一個元素了,將指針重置即可
if (elements == 1) {
end = -1;
front = 0;
elements = 0;
} else {
elements--;
}
return value;
}
//查看數據,從隊頭查看
public Object peek() {
return arr[front];
}
//判斷是否為空
public boolean isEmpty() {
return elements == 0;
}
public boolean isFull() {
return elements == arr.length;
}
public static void main(String[] args) {
MyQueue queue = new MyQueue(4);
queue.insert(11);
queue.insert(12);
queue.insert(13);
queue.insert(14);
queue.remove();
queue.remove();
queue.insert(16);
// queue.remove();
// queue.remove();
// queue.insert(19);
// queue.insert(20);
queue.remove();
queue.remove();
queue.insert(21);
queue.insert(22);
while (!queue.isEmpty()) {
System.out.println(queue.remove());
}
}
}