數據結構-模擬單向鏈表Scala實現

整體思路

今天介紹手動模擬單向鏈表。個人理解的鏈表的結構類似於 拆盒子游戲,表面上看存儲是一個鏈條結構,實際存儲是重複包裝的方式,我們需要實現的刪除,插入,更新 只是在層層盒子中間去掉盒子,增加盒子,該盒子的方式

首先是基本的存儲結構

單向鏈表的存儲結構如下,單向鏈表爲當前的 對象中有一個當前對象的屬性。可以理解爲 當前的盒子裏面不僅可以裝東西,還可以裝其他盒子

case class HeroNode(hNo:Int,hName:String,hNickName:String){
  var no = hNo
  var name = hName
  var nickname = hNickName
  var next:HeroNode = null

}

其次操作代碼

操作代碼的方式有點類似於遞歸,這裏使用的是while循環的方式,所有操作的基礎基本都是查找

代碼

package com.xipenhui.cn

object SingleLinkListDemo {

  def main(args: Array[String]): Unit = {
    val singleLinkList = new SingleLinkList
    val hero1 = HeroNode(1, "宋江", "及時雨")
    val hero2 = HeroNode(2, "盧俊義", "玉麒麟")
    val hero3 = HeroNode(3, "吳用", "智多星")
    val hero4 = HeroNode(4, "公孫勝", "入雲龍")
    singleLinkList.addNodetoTail(hero1)
    singleLinkList.addNodetoTail(hero2)
    singleLinkList.addNodetoTail(hero3)

    println("=====原始鏈表是========")
    singleLinkList.showLinkedList()

    singleLinkList.deleteNode(2)
    singleLinkList.updata(HeroNode(1, "宋江", "孝義黑三郎"))
    println("=======刪除後的鏈表是=======")
    singleLinkList.showLinkedList()

    println("==========按順序插入後是==========")
    singleLinkList.addNode2Pos(hero2)
    singleLinkList.showLinkedList()

    println("====往尾部插入=====")
    singleLinkList.addNode2Pos(hero4)
    singleLinkList.showLinkedList()
  }
}

/**
 * 1.刪除節點 先查找再刪除
 * 2.修改節點
 * 3.添加節點 添加到尾部
 * 4.添加節點到指定位置,根據排名添加到指定位置
 *
 */
class SingleLinkList {
  val head: HeroNode = HeroNode(0, "", "")

  // 刪除節點的方法
  def deleteNode(no: Int) {
    var temp = head
    var flag = true
    while (temp.next != null && flag) {
      if (temp.next.hNo == no) flag = false else temp = temp.next
    }
    if (temp.next == null) {
      println("not found element")
    } else {
      temp.next = temp.next.next
    }
  }

  // 在單向鏈表尾部添加一個元素
  def addNodetoTail(hero: HeroNode) {
    var temp = head
    if (hero == null) {
      throw new NullPointerException("input hero is null")
    }

    while (temp.next != null) {
      temp = temp.next
    }
    temp.next = hero
  }

  //顯示鏈表
  def showLinkedList(): Unit = {
    var temp = head
    if (temp.next == null) {
      println("this is a empty LinkedList")
    }
    var count = 0
    while (temp.next != null) {
      val hero = temp.next
      println(s"linkedList 第${count} 個元素是${hero.toString}")
      count += 1
      temp = temp.next
    }
  }

  //修改單節點的值,不修改編號
  def updata(hero: HeroNode): Unit = {
    var temp = head
    if (hero == null) {
      throw new NullPointerException("input hero is null")
    }
    var flag = true
    while (temp.next != null && flag) {
      //找到了該節點
      if (temp.next.no == hero.no) {
        //後面的節點被輸入節點指向
        hero.next = temp.next.next
        //前面的節點指向該節點
        temp.next = hero
        flag = false
      } else {
        //沒有找到指定節點,向後繼續移動
        temp = temp.next
      }
    }
    if (temp.next == null) {
      throw new RuntimeException("this hero is not exists")
    }
  }

  //添加單幾點到指定的位置 按照num的升序排列
  def addNode2Pos(hero: HeroNode): Unit = {
    var temp = head
    if (hero == null) {
      throw new NullPointerException("input hero is null")
    }
    var flag = true
    while (temp.next != null && flag) {
      if (temp.next.no > hero.no) {
        //可以在該節點前面插入數據
        hero.next = temp.next
        temp.next = hero
        flag = false
      } else if (temp.next.no < hero.no) {
        //指針後移
        temp = temp.next
      } else {
        // no重複,表示插入元素已存在
        throw new RuntimeException("hero is exists,if you want to updata hero ,use method update")
      }
    }

    //添加的元素比鏈表裏其他元素編號都大,直接添加到尾部
    if (temp.next == null) {
      addNodetoTail(hero)
    }
  }
}

case class HeroNode(hNo: Int, hName: String, hNickName: String) {
  var no = hNo
  var name = hName
  var nickname = hNickName
  var next: HeroNode = null

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