数据结构-模拟单向链表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

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