05.Java數據結構與算法之~隊列與環形隊列CircleArrayQueue
隊列的介紹
.隊列(queue)是隻允許在一端進行插入操作,而在另一端進行刪除操作的線性表
插入的一端稱爲隊尾,刪除的一端稱爲隊頭
隊列是一個有序列表,可以用數組或是鏈表實現
隊列的缺點:
出隊複雜度高 O(n),容易假溢出
隊列的鏈式存儲及結構模式
隊列的鏈式存儲結構,其實就是線性表的單鏈表,只不過它只能從尾進,從頭出而已。
空隊列->>數組模擬隊列
創建Queue接口
public interface Queue{
boolean isFull();
boolean isEmpty();
void add(Object n);
Object get();
String toString();
Object Head();
int size();
}
數組模擬隊列代碼實現
//使用數組模擬隊列,編寫一個ArrayQueued類
public class ArrayQueue implements Queue{
private int maxSize; //表示數組的最大容量
private int front; //隊列頭
private int rear; //隊列尾
private Object[]arr; //存放數據
private int size; //隊列的大小,如果初始值是16,用戶沒填滿,遍歷時防止出現NULL
private final int INITIAL=16; //初始大小爲16
//創建隊列的構造器
public ArrayQueue(int arrMaxSize){
maxSize = arrMaxSize;
arr = new Object[maxSize];
front = -1; //面向隊列頭部,指向隊列頭的前一個位置
rear = -1; //面向隊列尾
}
//如果用戶沒設置大小,則默認爲初始大小
public ArrayQueue(){
maxSize = INITIAL;
arr = new Object[INITIAL];
front = -1;
rear = -1;
}
//判斷隊列是否已滿
public boolean isFull(){
return rear == maxSize-1;
}
//判斷隊列是否爲空
@Override
public boolean isEmpty(){
return front == rear;
}
//添加數據到隊列
@Override
public void add(Object n){
if(isFull()){
throw new IndexOutOfBoundsException("隊列滿!");
}
rear++; //讓rear後移
size++; //讓大小增加
arr[rear] = n;
}
//返回隊列長度
@Override
public int size(){
return size - (front + 1);
}
//獲取隊列數據,出隊列
@Override
public Object get(){
//判斷隊列是否空
if(isEmpty()){
throw new NullPointerException("隊列爲空!");
}
front++; //讓front後移
return arr[front];
}
//遍歷隊列
@Override
public String toString(){
if(isEmpty()){
throw new NullPointerException("隊列爲空!");
}
StringBuilder stringBuilder = new StringBuilder("[");
//循環到隊列的倒數第二個位置結束循環,防止多加一個逗號妨礙美觀
for(int i = front + 1; i < size - 1; i++){
stringBuilder.append(arr[i] + ",");
}
//添加最後一個數據
stringBuilder.append(arr[size-1] + "]");
return stringBuilder.toString();
}
//返回頭數據
@Override
public Object Head(){
//判斷是否爲空
if(isEmpty()){
throw new NullPointerException("隊列空!");
}
return arr[front+1];
}
}
環形數組隊列模擬
把隊列的這種頭尾相接的順序存儲結構稱爲循環隊列
變量的含義做一個調整:front指向第一個元素,rear指向最後一個元素
隊列的構造器
//由於front和rear默認爲0,所以不需要賦值了
public CircleArrayQueue(int arrMaxSize){
maxSize = arrMaxSize;
arr = new Object[maxSize];
}
判斷隊列是否已滿
public boolean isFull(){
return (rear + 1) % maxSize == front;
}
添加數據到隊列
@Override
public void add(Object n){
if(isFull()){
throw new IndexOutOfBoundsException("隊列滿!");
}
arr[rear] = n;
//將rear後移
rear = (rear + 1) % maxSize;
}
獲取隊列數據,出隊列
先把front對應的值保存到一個臨時變量,將front後移,返回臨時變量
public Object get(){
//判斷隊列是否空
if(isEmpty()){
throw new NullPointerException("隊列爲空!");
}
Object value = arr[front];
front = (front + 1) % maxSize;
return value;
}
求長
public int size(){
return (rear + maxSize - front) % maxSize;
}
代碼實現
public class CircleArrayQueue implements Queue{
private int maxSize; //表示數組的最大容量
private int front; //隊列頭
private int rear; //隊列尾
private Object[]arr; //存放數據
private final int INITIAL=16; //初始大小爲16
//創建隊列的構造器
public CircleArrayQueue(int arrMaxSize){
maxSize = arrMaxSize;
arr = new Object[maxSize];
}
//如果用戶沒設置大小,則默認爲初始大小
public CircleArrayQueue(){
maxSize = INITIAL;
arr = new Object[INITIAL];
}
//判斷隊列是否已滿
public boolean isFull(){
return (rear + 1) % maxSize == front;
}
//判斷隊列是否爲空
@Override
public boolean isEmpty(){
return front == rear;
}
//添加數據到隊列
@Override
public void add(Object n){
if(isFull()){
throw new IndexOutOfBoundsException("隊列滿!");
}
arr[rear] = n;
//將rear後移
rear = (rear + 1) % maxSize;
}
//獲取隊列數據,出隊列
@Override
public Object get(){
//判斷隊列是否空
if(isEmpty()){
throw new NullPointerException("隊列爲空!");
}
Object value = arr[front];
front = (front + 1) % maxSize;
return value;
}
//隊列長度
@Override
public int size(){
return (rear + maxSize - front) % maxSize;
}
//遍歷隊列
@Override
public String toString(){
if(isEmpty()){
throw new NullPointerException("隊列爲空!");
}
StringBuilder stringBuilder = new StringBuilder("[");
//循環到隊列的倒數第二個位置結束循環,防止多加一個逗號妨礙美觀
for(int i = front ; i < rear - 1; i++){
stringBuilder.append(arr[i] + ",");
}
//添加最後一個數據
stringBuilder.append(arr[rear-1] + "]");
return stringBuilder.toString();
}
//返回頭數據
@Override
public Object Head(){
//判斷是否爲空
if(isEmpty()){
throw new NullPointerException("隊列空!");
}
return arr[front];
}
}