102、數組實現隊列

一、隊列實現的方式

數組存儲隊列方式
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
//  }


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章