一、隊列實現的方式
數組存儲隊列方式:
1、指定隊列大小不重複使用,相當於一次性使用
2、每次出隊一個元素,數組整體向前移動一步;入隊根據座標,快,出隊需要遷移,慢
3、循環隊列,空間多次複用,使用隊列時不能將隊列填滿,需要空出一個位置(推薦)
鏈表實現隊列: 鏈表實現隊列,出隊快,入隊慢
1、單向隊列:移除節點需要臨時節點
2、雙向隊列:移除節點不需要臨時節點
3、循環對了:特殊場景使用,如約瑟夫問題:數數退
二、數組與鏈表實現區別
數組優點:數組實現方式數據入隊快,因爲根據索引
數組缺點:數據擴容時的數據遷移會佔用大量時間,以及每次擴容因子等計算
鏈表優點:數據出隊快,只需要將待刪除節點指引從鏈表中移除即可
鏈表缺點:數據入隊需要對鏈表遍歷,找到隊尾;(可用兩個頭尾臨時節點來解決此問題)
三、代碼實現
1、數組實現
1.1 一次性隊列
package com.cjy.chapter19.queue
object ArrayQueue01 {
def main(args: Array[String]): Unit = {
val queue0 = new ArrayQueue01(10)
(0 to 9).foreach(queue0.addEle(_))
queue0.showQueue()
println()
for (i <- 0 to 5) {
println(queue0.getQueue())
}
println("隊首查看")
println(queue0.showHead())
}
}
/**
* 數組存儲隊列方式:
* 1、指定隊列大小不重複使用,相當於一次性使用
* 2、每次出隊一個元素,數組整體向前移動一步;入隊快,出隊慢
* 3、循環隊列,空間多次複用(推薦)
*/
//方式一:一次性隊列
class ArrayQueue01(val newmaxSize: Int) {
val maxSize = newmaxSize //隊列最大容量
val array = new Array[Int](maxSize) //隊列實際容器
var first = -1 //隊列頭
var last = -1 //隊列尾
//隊列已滿
def isFull() = {
if (maxSize - 1 == last) {
true
} else {
false
}
}
//隊列爲空
def isEmpty() = {
if (first == last) {
true
} else {
false
}
}
//入隊
def addEle(ele: Int) = {
if (isFull()) {
throw new IllegalArgumentException("隊列已滿。。。。")
}
//隊尾後移
last += 1
//添加元素
array(last) = ele
ele
}
//出隊
def getQueue() = {
if (isEmpty()) {
throw new IllegalArgumentException("隊列爲空。。。。")
}
first += 1
array(first)
}
//頭節點查看
def showHead() = {
if (isEmpty()) {
throw new IllegalArgumentException("隊列爲空。。。。")
}
array(first + 1)
}
//隊列查看
def showQueue(): Unit = {
if (isEmpty()) {
throw new IllegalArgumentException("隊列爲空。。。。")
}
array.foreach(x => {
print(x + "\t")
})
}
//隊列中元素個數
def size() = {
if (isEmpty()) {
0
}else{
last - first
}
}
}
1.2 循環隊列-自動擴容機制
package com.cjy.chapter19.queue
/**
* 方式三:循環隊列
* 注意事項:
* 1、需要空出一個位置,因爲last是指向最後一個元素下個座標的,例如當前有9元素,last=9,(9+1)%10=0,所以會空置出來一個元素
* 2、first==last 時隊列空
* 3、隊列中元素個數 size 計算
* 4、出隊、入隊座標計算,加1 取模 maxSize
* 5、擴容機制,注意擴容因子,縮容因子,數據移動式數據初始化,必須先確定last值再確定first,不然last會受影響
*/
object ArrayQueue02 {
def main(args: Array[String]): Unit = {
val queue0 = new ArrayQueue02(10)
// (0 to 8).foreach(println(_))
(0 to 15).foreach(queue0.addEle(_))
queue0.showQueue()
println("長度:"+queue0.size())
println("frist:"+queue0.first)
println("last:"+queue0.last)
for (i <- 0 to 10) {
println(queue0.getQueue())
}
println("出隊11個元素")
queue0.showQueue()
println("長度:"+queue0.size())
println("frist:"+queue0.first)
println("last:"+queue0.last)
// println("再入隊4個")
// (0 to 3).foreach(queue0.addEle(_))
// queue0.showQueue()
// println("隊首查看")
// println(queue0.showHead())
println("-------------測試數據擴容機制")
}
}
class ArrayQueue02(val newmaxSize: Int) {
var maxSize:Int = newmaxSize //隊列最大容量
var array = new Array[Int](maxSize) //隊列實際容器
var first = 0 //隊列頭
var last = 0 //隊列尾
//隊列是否滿了
//判斷隊列滿的方法
//隊列容量空出一個作爲約定 以爲:last=9時,(9+1)%10=0,其實此時隊列是滿的狀態
def isFull() = {
(last + 1) % maxSize == first
}
//隊列爲空
def isEmpty() = {
last == first
}
//入隊
def addEle(ele: Int):Int = {
if (isFull()) {
println("隊列已滿。。。。")
return ele
}
//檢測數據達到80%,進行2倍擴容
if(size() >= maxSize*0.8){
addSize(maxSize*2,array)
}
//添加元素
array(last) = ele
//隊尾後移
last = (last + 1) % maxSize
ele
}
//出隊
def getQueue() = {
if (isEmpty()) {
throw new IllegalArgumentException("隊列爲空。。。。")
}
if(size() <= maxSize/3){
addSize(maxSize/2,array)
}
val i = array(first)
first = (first + 1) % maxSize
i
}
//頭節點查看
def showHead() = {
if (isEmpty()) {
throw new IllegalArgumentException("隊列爲空。。。。")
}
array(first)
}
//隊列查看
def showQueue(): Unit = {
if (isEmpty()) {
throw new IllegalArgumentException("隊列爲空。。。。")
}
for(i <- 0 until size()){
println(array((first+i)%maxSize))
}
}
//隊列中元素個數
def size() = {
(last + maxSize - first) % maxSize
}
//數據擴容
def addSize(nweSize:Int,arr:Array[Int]): Unit ={
println("擴容機制觸發:"+nweSize)
var newArr = new Array[Int](nweSize)
for(i <- 0 to size() - 1){
newArr(i) = array((first + i)%maxSize)
}
last = size() //隊尾是長度,所以先賦值
first = 0 //新的數組隊首是0,後改,不然會影響last計算
array = newArr //數組重新指向
maxSize = nweSize //修改最大容量
}
// def subSize(size:Int,arr:Array[Int]): Unit ={
// val newArr = new Array[Int](size)
// maxSize = size
// for(i <- 0 to size()-1){
// newArr(i) = array((first + i)%maxSize)
// }
// array = newArr
// }
}