佇列是乙個有序列表,可以使用陣列或鍊錶來實現。
佇列遵循先進先出的原則。即:先存入佇列的資料,要先取出。後存入的要後取出。
因為佇列的輸入、輸出分別是從前後兩端來處理的,所以定義兩個變數front、rear來分別表示佇列的前後端的下標。
下面就用**來實現簡單的佇列。
因為這裡涉及到了兩種不同結構的佇列,普通的佇列與環形佇列。所以這裡編寫乙個抽象類(abstractqueue),記錄佇列的公共方法。
佇列都有新增資料(入佇列)、獲取資料(出佇列)、列印資料(顯示佇列所有資料)、顯示頭資料等方法。
public
abstract
class
abstractqueue
下面就通過實現這個類,來實現陣列模擬佇列。
public
class
arrayqueue
extends
abstractqueue
/** * todo 判斷佇列是否 充滿
*/public
boolean
isfull()
/** * todo 判斷佇列是否為空
*/public
boolean
isempty()
/** * todo 新增資料(入佇列)
*/@override
public
void
enterqueue
(int n)
// 後移
this
.rear++
;this
.arr[
this
.rear]
= n;
}/**
* todo 從佇列中獲取資料(出佇列)
*/@override
public
intoutqueue()
// 後移
this
.front++
;return
this
.arr[
this
.front];}
/** * todo 顯示佇列的所有資料
*/@override
public
void
listqueue()
for(
int i =
0; i <
this
.arr.length; i++)}
/** * todo 顯示 佇列 的 頭資料
*/@override
public
intheadqueue()
return
this
.arr[
this
.front +1]
;}}
這裡我們將佇列的前端(front)與佇列的後端(rear)的初始值都設為 -1 。
判斷佇列是否已滿:this.rear == this.maxsize - 1。
判斷佇列是否為空:this.rear == this.front。
上面的**都很簡單,基本都有注釋,下面編寫測試類。
public
class
test
private
static
void
testqueue
(abstractqueue queue)
catch
(exception e)
break
;case
'e':
flag = boolean.false;
scanner.
close()
;break
;case
'a':
system.out.
println
("請輸入乙個數:");
int value = scanner.
nextint()
; queue.
enterqueue
(value)
;break
;case
'g':
trycatch
(exception e)
break
;default
:break;}
} system.out.
println
("程式已退出");
}}
至於測試結果就不給出了,感興趣的讀者,可直接複製**,執行即可。
從上面的陣列模擬佇列可以看出。當佇列充滿的時候,就算從佇列中取出資料,新的資料也不能新增到佇列中。這樣就造成了大量的空間浪費。所以為了充分利用陣列。就要用將陣列轉換為環形佇列。
public
class
ringarrayqueue
extends
abstractqueue
/** * todo 判斷佇列是否滿(例如陣列長度(maxsize)為3,則rear就為3[最後乙個元素的角標為 2 + 1],)
*/public
boolean
isfull()
/** * todo 判斷佇列是否為空
*/public
boolean
isempty()
/** * todo 新增資料(入佇列)
*/@override
public
void
enterqueue
(int n)
arr[rear]
= n;
// 取模, rear後移
rear =
(rear +1)
% maxsize;
}/**
* todo 獲取資料(出佇列)
*/@override
public
intoutqueue()
// 1. 先把 front 對應的值保留到乙個臨時變數
int temp = arr[front]
;// 2. 取模,將 front 後移
front =
(front +1)
% maxsize;
// 3. 將臨時儲存的變數返回
return temp;
}/**
* todo 顯示佇列所有的資料
*/@override
public
void
listqueue()
// 從front開始遍歷,遍歷多少個元素
for(
int i = front; i < front +
size()
; i++)}
/** * todo 顯示頭部元素
*/@override
public
intheadqueue()
return arr[front];}
/** * todo 有效資料的個數
*/private
intsize()
}
判斷佇列是否已滿:(rear + 1) % maxsize == front。
判斷佇列是否為空:this.rear == this.front。
上面的**基本上也有注釋,環形佇列理解起來還是有點繞,盡可能的畫圖跟**慢慢理解吧。測試方法就和測試普通的佇列一樣。因為環形佇列也是繼承自abstractqueue他們有公用的方法,所以測試方法就能重用了。
public
static
void
main
(string[
] args)
資料結構與演算法 佇列
學習了好長 一段時間的資料結構,由於時間關係一直沒有寫部落格。這次打算將這段時間的學習內容寫下來做個整理。佇列作為線性結構的一種,其實用性不用多說。這裡總結下兩種結構的佇列實現。迴圈佇列 先列下以順序表結構形成的普通順序佇列存在的問題 隊頭不斷刪除元素,將使佇列的頭部空出單元 隨著刪除 插入的進行,...
資料結構與演算法 佇列
佇列 佇列與棧不同,它是一種先進先出的結構 實現 1 陣列 2 鍊錶 記錄的資料 1 隊首位置 第乙個元素的位置 2 隊尾位置 最後乙個元素的位置 3 佇列大小 size 佇列操作 entryqueue 入隊 exitqueue 出隊 isqueueempty 隊列為空 isqueuefull 佇列...
演算法與資料結構 佇列
adt queue d d 資料關係 r r a i d,i 2,3,n r 約定a 1a 1 a1 端為隊首,a na n an 端為隊尾。基本操作 create 建立乙個空佇列 emptyque 若隊列為空,則返回true,否則返回false insertque x 向隊尾插入元素x delet...