整體思路
今天介紹手動模擬單向鏈表。個人理解的鏈表的結構類似於 拆盒子游戲,表面上看存儲是一個鏈條結構,實際存儲是重複包裝的方式,我們需要實現的刪除,插入,更新 只是在層層盒子中間去掉盒子,增加盒子,該盒子的方式
首先是基本的存儲結構
單向鏈表的存儲結構如下,單向鏈表爲當前的 對象中有一個當前對象的屬性。可以理解爲 當前的盒子裏面不僅可以裝東西,還可以裝其他盒子
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
}