java单向链表

package datastructure.linkedList

import java.util

import scala.util.control.Breaks

class HeroNode{
  var no: Int = _
  var name: String = _
  var nickName: String = _
  var next: HeroNode = _ //指向下一个结点
  def this(hNo: Int, name: String,nick: String) = {
    this()
    this.no = hNo
    this.name = name
    this.nickName = nick
  }

  override def toString: String = {
    s"HeroNode{no=$no, name= $name, nickName= $nickName}"
  }
}

class SingleLinkedList{
  //先初始化一个头节点
  private val head = new HeroNode(0,"","")

  def getHead: HeroNode = {
    head
  }
  /**
   * 顺序添加元素
   * @param node 添加的节点
   */
  def add(node: HeroNode): Unit = {
    //当不考虑编号的顺序,找到链表的最后节点,将next指向node这个节点
    var temp = head
    val control = new Breaks
    //遍历链表找到最后
    control.breakable(
      while (true){
        //找到链表的最后
        if(temp.next == null){
          control.break()
        }
        //没有找到最后就后移
        temp = temp.next
      }
    )
    temp.next = node
  }

  /**
   * 按照no顺序取添加
   * @param node 插入的节点
   */
  def addByOrder(node: HeroNode): Unit = {
    //单链表 temp的位置是插入的节点的前一个位置,否则加入不了
    var temp = head
    var flag = false //编号是否存在
    val control = new Breaks
    //遍历链表找到插入位置
    control.breakable(
      while (true){
        //找到链表的最后
        if(temp.next == null){
          control.break()
        }
        if(temp.next.no > node.no){//位置找到插入即可
            control.break()
        }else if(temp.next.no == node.no){
          flag = true//编号存在
          control.break()
        }
        //没有找到最后就后移
        temp = temp.next
      }
    )
    //判断flag值
    if(flag) println(s"编号${node.no}已存在,不能添加")
    else { //插入操作
      node.next = temp.next
      temp.next = node
    }
  }


  /**
   * 根据no来修改节点信息
   * @param node 修改的节点
   */
  def update(node: HeroNode): Unit = {
      if(head.next == null) {
        println("链表为空")
        return
      }
    var temp = head.next
    var flag = false //表示是否找到节点
    val control = new Breaks
    //遍历链表找到最后
    control.breakable(
      while (true){
        //找到链表的最后
        if(temp.next == null){
          control.break()
        }
        if(temp.no == node.no){
          flag = true
          control.break()
        }
        temp = temp.next
      }
    )
    if(flag){
      temp.name=node.name
      temp.nickName=node.nickName
    } else {
      println(s"没有找到该节点${node.no}")
    }
  }

  /**
   * 找到待删除节点的前一个节点直接引向后两个节点
   * @param node 待删除节点
   */
  def delete(node: HeroNode): Unit = {
    var temp = head
    var flag = false
    val control = new Breaks
    control.breakable(
      while (true){
        if(temp.next == null){ //链表最后
          control.break()
        }
        if(temp.next.no == node.no ){//找到前一个几点
          flag = true
          control.break()
        }
        temp = temp.next
      }
    )
    if(flag) temp.next = temp.next.next
    else {
      println(s"没有找到该节点${node.no}")
    }
  }



  /**
   * 获取倒数第K个节点
   * 1.首先获取长度size
   * 2.在遍历size-1次即可
   * @param head 头节点
   * @param index 倒数第几个
   */
  def getLastK(head: HeroNode, index: Int) :HeroNode = {
    var res: HeroNode = null
    if(head.next == null){
      res
    }else {
      val size = SingleLinkedList.size(head)
      if(index <=0 || index>size){
        res
      } else{
         res = head.next
        for (_ <- 0 until (size-index)){
          res = res.next
        }
        res
      }
    }

  }

  /**
   * 展示单链表
   */
  def show(): Unit = {
    if(head.next == null){
      println("链表为空")
      return
    }
    var temp = head.next
    val control = new Breaks
    //遍历链表找到最后
    control.breakable(
      while (true){
        //找到链表的最后
        if(temp == null){
          control.break()
        }
        //没有找到最后就后移
        println(temp)
        temp = temp.next
      }
    )
  }

  /**
   * 逆序打印单链表且不破坏链表结构
   * 遍历单链表放入栈中再取出
   */
  def reverseShow():Unit = {
    if(head.next == null){
      println("链表为空")
      return
    }
    var temp = head.next
    val nodes = new util.Stack[HeroNode]
    //遍历链表找到最后
    while (temp != null){
      //入栈
      nodes.push(temp)
      //没有找到最后就后移
      temp = temp.next
    }
    while (nodes.size() > 0){
      //出栈
      println(nodes.pop())
    }
  }
}
object SingleLinkedList{
  /**
   * 链表的有效长度(不包括头节点)
   * @return
   */
  def size(head: HeroNode): Int = {
    var len = 0
    if(head.next == null){
      len
    }else {
      var temp = head.next
      while (temp != null){
        len += 1
        temp = temp.next
      }
      len
    }

  }

  /**
   * 将单链表反转
   * @param head 链表的头节点
   */
  def reverse(head: HeroNode): Unit = {
    if(head.next == null || head.next.next==null) {
      return
    }
    var cur = head.next
    var next: HeroNode = null //指向当前节点的下一个结点
    var renext: HeroNode = null //指向当前节点的下一个结点
    val reHead = new HeroNode(0, "", "")
    //遍历原来的链表,每遍历一个节点,将其取出放在反转链表的最前端
    while (cur!= null){
      //保存当前节点的下一个节点(防止断链)
      next = cur.next
      renext = reHead.next
      //将当前节点的下一个节点指向新链表的最前端
      cur.next=renext
      reHead.next = cur
      cur = next  //让cur后移
    }
    //将head.next指向reverseHead.next
    head.next = reHead.next

  }
}
object SingleLinkedListDemo {
  def main(args: Array[String]): Unit = {
    val hero1 = new HeroNode(1, "宋江", "及时雨")
    val hero2 = new HeroNode(2, "卢俊义", "玉麒麟")
    val hero3 = new HeroNode(3, "林冲", "豹子头")
    val hero4 = new HeroNode(4, "吴用", "智多星")
    val list = new SingleLinkedList()
    list.addByOrder(hero1)
    list.addByOrder(hero4)
    list.addByOrder(hero3)
    list.addByOrder(hero2)
    println("按照编号顺序添加元素")
    list.show()
    val hero5 = new HeroNode(2, "小卢", "玉麒麟~~")
    println("修改元素信息")
    list.update(hero5)
    list.show()
    println("删除后")
    list.delete(hero1)
    list.show()
    println("链表长度")
    println(SingleLinkedList.size(list.getHead))
    println(list.getLastK(list.getHead, 2))
    println("单链表反转")
    SingleLinkedList.reverse(list.getHead)
    list.show()
    println("逆序打印")
    list.reverseShow()
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值