佇列是一種特殊的線性表。
佇列元素的進出遵循「先進先出」原則:即只允許在前端(front)也就是隊頭進行刪除操作,而只能在後端(rear)也就是隊尾進行插入操作。
如圖所示:
/**
* @author:huang
* @date:2020-06-11 16:28
* @description:用陣列模擬佇列
*/public class queue
/*** 判斷佇列是否為空
** @return
*/public boolean isempty()
/*** 判斷佇列是否已滿
* @return
*/public boolean isfull()
/*** 入隊
* @param item 入隊元素
* @return
*/public int addqueue(object item)
//尾指標後移
rear++;
arr[rear] = item;
return rear;
}/**
* 出隊
* @return
*/public object quitqueue()
//頭指標後移
front++;
return arr[front];}}
咋一眼看上去沒問題,但是實際上隨著入隊和出隊操作,頭指標和尾指標會不斷後移,最後都到達maxsize-1的位置,此時即使實際上有空閒空間也無法往裡面新增資料了。
如果要解決這個問題,可以這樣改進:
當入隊的時候進行一次判斷,如果尾指標已經移動到maxsize-1的位置,並且頭指標不在-1位置,也就是佇列仍然還有空位,就觸發一次資料遷移。
打個比方,如果佇列長度為6,現在頭指標在3,尾指標在5,觸發資料遷移後下標3-5的資料移動到0-2去,然後把頭指標移到0,尾指標移到2。
基於這個邏輯,只需要改變一下addqueue()
入隊方法即可:
/**
* 入隊
* @param item 入隊元素
* @return
*/public int addqueue(object item) else
//移動指標
rear = rear - front;
front = -1;}}
//尾指標後移
rear++;
arr[rear] = item;
return rear;
}
雖然問題解決了,但是頻繁的移動資料會消耗效能,為此仍需要加以改進:
當尾指標到頭以後,如果頭指標前還有空閒空間,尾指標應當能移動到頭指標之前的位置,也就是隊頭元素出隊了,空出的空間將可以放在隊尾被元素入隊。
打個比方,就相當於原本的佇列是一條直線,走到頭就沒了,現在要把頭和尾連線到一起,讓它變成迴圈佇列。
對於迴圈佇列,有兩個問題需要考慮,乙個是下標,另乙個是隊空和隊滿的判斷條件
由於隊頭元素出隊後空間即用於隊尾元素入隊,所以很可能出現長度5的佇列,頭指標在1,尾指標在4,這個時候在按照原來的思路用rear+1去入隊就會下標越界,因此需要進行取餘操作,也就是(rear+1)% maxsize
,這樣獲取下標的問題就解決了。
由於佇列變為環形,所以front=rear即可能是隊滿也可能是隊空,針對這個問題有兩種思路:
第一種是新增乙個變數來記錄佇列中元素的數量,以區分front=rear時是隊滿還隊空;
第二種是在rear後預留乙個空位,通過計算判斷rear+1後是否等於front以判斷隊滿還是隊空;
這裡先用第二種來實現一下:
/**
* @author:huang
* @date:2020-06-14 16:13
* @description:環形佇列
*/public class criclequeue
/*** 判斷佇列是否為空
** @return
*/public boolean isempty()
/*** 判斷佇列是否已滿
* @return
*/public boolean isfull()
/*** 入隊
* @param item
*/public void addqueue(object item)
arr[rear] = item;
rear = (rear + 1) % maxsize;
}/**
* 出隊
* @return
*/public object quitqueue()
object item = arr[front];
front = (front + 1) % maxsize;
return item;}}
常用資料結構之一佇列
常用資料結構之一佇列 佇列是一種特殊的 線性表,特殊之處在於它只允許在表的前端 front 進行刪除操作,而在表的後端 rear 進行插入操作,和棧一樣,佇列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。佇列中沒有元素時,稱為空佇列。佇列的資料元素又稱為佇列元素。在佇...
學習資料結構(一) 佇列(2)
留下筆記。mycircularqueue k 構造器,設定佇列長度為 k front 從隊首獲取元素。如果隊列為空,返回 1 rear 獲取隊尾元素。如果隊列為空,返回 1 enqueue value 向迴圈佇列插入乙個元素。如果成功插入則返回真。dequeue 從迴圈佇列中刪除乙個元素。如果成功刪...
資料結構學習一佇列整理
class myqueue 入隊成功了,返回true public boolean enqueue int x 出隊,成功返回true public boolean dequeue p start return true 獲取隊首元素 public intfront c判斷佇列是否為空 public...