Scala简单实现单链表的增、删、改

近期有学习scala这门编程语言,为了熟悉下相关语法,这里使用scala语言实现了一个单链表,改链表的功能包括:新增节点、删除节点、更新节点、打印链表信息等,以下是具体的实现,附带全部的代码实现和备注说明,可正常运行,有实现结果。

一、定义节点

  /**
   * 节链表点定义
   * @param hNo 编号
   * @param hName 姓名
   * @param hNickName 昵称
   */
  class HeroNode(hNo: Int, hName: String, hNickName: String) {
    var no: Int = hNo
    var name: String = hName
    var nickName: String = hNickName
    var next: HeroNode = _

    override def toString: String = s"no:$no\tname:$name\tnickName:$nickName"
  }

二、定义链表类

 // 链表类定义
  class SingleLinkedList {
    // 头节点
    var head: HeroNode = _
    // 排序类型,默认不排序
    var orderType: Int = LinkOrderType.NO_ORDER

    /**
     * 定义排序类型的构造器
     * @param orderType 排序类型
     */
    def this(orderType: Int) {
      this()
      this.orderType = orderType
    }

    /**
     * 初始化头结点的构造器
     * @param head 头节点
     */
    def this(head: HeroNode) {
      this()
      this.head = head
    }

    /**
     * 初始化头结点的构造器
     * @param head 头节点
     * @param orderType 排序类型
     */
    def this(head: HeroNode, orderType: Int) {
      this()
      this.head = head
      this.orderType = orderType
    }
}

三、链表功能实现

在SingleLinkedList类中实现添加节点、更新节点、删除节点、打印节点等。实现中考虑了排序规则,所以这里定义了一个排序常量。

  // 排序类型定义
  case object LinkOrderType {
    // 无排序
    val NO_ORDER:Int = 0
    // 降序排列
    val DESC_ORDER:Int = 1
    // 升序排列
    val ASC_ORDER:Int = 2
  }

以下逐一对各个功能进行实现

1、添加节点

/**
     * 添加链表节点
     * @param node 节点
     */
    def add(node: HeroNode): Unit = {
      if (head == null) {
        // 新加入节点为头节点
        head = node
        return
      }

      // 排序检查
      if (orderType != LinkOrderType.NO_ORDER) {

        var hc:Boolean = false;
        if (orderType == LinkOrderType.ASC_ORDER) {
          // 升序
          hc = head.no > node.no
        } else if (orderType == LinkOrderType.DESC_ORDER) {
          // 降序
          hc = head.no < node.no;
        }

        if (hc) {
          // 与头结点进行排序比较
          node.next = head
          head = node
          return
        }
      }

      if (head.no == node.no) {
        println(s"节点 ${node} 已存在,无需重复添加")
        return
      }

      // 从头节点开始
      var temp = head

      // 节点是否已存在
      var existFlag = false
      breakable {
        while (true) {
          if (temp.next == null) {
            // 说明已经到最后一个节点了
            if (temp.no == node.no) {
              // 节点已存在
              existFlag = true
            } else {
              // 加入到链表
              temp.next = node
            }
            // 最后一个节点退出循环
            break()
          } else {
            // 排序检查
            if (orderType != LinkOrderType.NO_ORDER) {
              var nc:Boolean = false;
              if (orderType == LinkOrderType.ASC_ORDER) {
                // 升序
                nc = temp.next.no > node.no
              } else if (orderType == LinkOrderType.DESC_ORDER) {
                // 降序
                nc = temp.next.no < node.no;
              }
              if (nc) {
                node.next = temp.next
                // 加入到链表
                temp.next = node
                // 根据排序规则在对应已加入,循环退出
                break()
              }
            }

            if (temp.next.no == node.no) {
              existFlag = true
              // 节点已存在,退出循环
              break()
            }
            // 继续遍历下一个节点
            temp = temp.next
          }
        }
      }
      if (existFlag) {
        println(s"节点 ${node} 已存在,无需重复添加")
        return
      }
    }

2、更新节点

/**
     * 更新链表节点
     * @param node 节点
     */
    def update(node: HeroNode): Unit = {
      if (head == null) {
        println("链表为空!!!")
        return
      }
      if (head.no == node.no) {
        println(s"no为${head.no}的首节点【${head}】已更新为【${node}】")

        node.next = head.next
        head = node
        return
      }

      // 从头节点的下一个节点开始
      var temp = head.next
      // 节点是否已存在
      var existFlag = false
      breakable {
        while (true) {
          if (temp.no == node.no) {
            // 找到了,直接替换
            existFlag = true
            println(s"no为${temp.no}的节点【${temp}】已更新为【${node}】")

            node.next = temp.next
            temp = node
            break()
          } else if (temp.next == null) {
            // 最后一个节点了,退出循环
            break()
          }
          // 继续遍历下一个节点
          temp = temp.next
        }
      }
      if (!existFlag) {
        // 不存在
        println(s"不存在no为${node.no}的节点,无数据更新")
      }
    }

3、删除节点

/**
     * 根据编号删除链表
     * @param no 编号
     */
    def delete(no: Int): Unit = {
      if (head == null) {
        println("链表为空!!!")
        return
      }
      if (head.no == no) {
        println(s"no为${head.no}的首节点已被移除")

        head = head.next
        return
      }

      // 从头节点开始
      var temp = head
      // 节点是否已存在
      var existFlag = false
      breakable {
        while (true) {
          if (temp.next == null) {
            // 最后一个节点了,退出循环
            break()
          } else if (temp.next.no == no) {
            // 找到了,直接删除
            existFlag = true
            println(s"no为${temp.next.no}的节点已被删除")

            temp.next = temp.next.next
            break()
          }
          // 继续遍历下一个节点
          temp = temp.next
        }
      }
      if (!existFlag) {
        // 不存在
        println(s"不存在no为${no}的节点,无数据删除")
      }
    }

4、打印链表信息

  /**
     * 链表内容打印
     */
    def printLink(): Unit = {
      println("================打印链表——开始==================")
      if (head == null) {
        println("链表为空!!!")
        return
      }
      var temp = head
      breakable{
        while (true) {
          if (temp != null) {
            printf("no:%d\tname:%s\tnickName: %s\n", temp.no, temp.name, temp.nickName)
          } else {
            // 节点最后了
            break()
          }
          temp = temp.next
        }
      }
      println("================打印链表——结束==================")
    }


    /**
     * 打印排序信息
     */
    def printOrderInfo(): Unit = {
      this.orderType match {
        case LinkOrderType.NO_ORDER => println("=========链表没有排序=========")
        case LinkOrderType.ASC_ORDER => println("=========链表升序排列=========")
        case LinkOrderType.DESC_ORDER => println("=========链表降序排列=========")
        case _ => println("=========链表未正确指定排序规则=========")
      }
    }

四、功能测验

1、测验代码

def main(args: Array[String]): Unit = {
//    val singleLinkedList = new SingleLinkedList()
//    val singleLinkedList = new SingleLinkedList(LinkOrderType.DESC_ORDER)
    val singleLinkedList = new SingleLinkedList(LinkOrderType.ASC_ORDER)
    singleLinkedList.printLink()
    // 打印排序信息
    singleLinkedList.printOrderInfo()

    val node1 = new HeroNode(1, "宋江1", "及时雨1")
    val node2 = new HeroNode(2, "宋江2", "及时雨2")
    val node4 = new HeroNode(4, "宋江4", "及时雨4")
    singleLinkedList.add(node2)
    singleLinkedList.add(node4)
    singleLinkedList.add(node1)
    singleLinkedList.printLink()

    // 重复添加
    singleLinkedList.add(node4)

    val node3 = new HeroNode(3, "宋江3", "及时雨3")
    val node6 = new HeroNode(6, "宋江6", "及时雨6")
    val node5 = new HeroNode(5, "宋江5", "及时雨5")
    singleLinkedList.add(node6)
    singleLinkedList.add(node5)
    singleLinkedList.add(node3)
    singleLinkedList.printLink()

    val node6u = new HeroNode(6, "宋江6-更新", "及时雨6-更新")
    val node7u = new HeroNode(7, "宋江7", "及时雨7")
    // 更新已存在
    singleLinkedList.update(node6u)
    singleLinkedList.printLink()
    // 更新不存在的记录
    singleLinkedList.update(node7u)
    singleLinkedList.printLink()

    // 删除中间的记录
    singleLinkedList.delete(5)
    // 删除首尾记录
    singleLinkedList.delete(1)
    singleLinkedList.delete(6)
    // 删除不存在的记录
    singleLinkedList.delete(8)
    singleLinkedList.printLink()
  }

2、测验结果

运行main方法,其测验结果如下:

================打印链表——开始==================
链表为空!!!
=========链表升序排列=========
================打印链表——开始==================
no:1	name:宋江1	nickName: 及时雨1
no:2	name:宋江2	nickName: 及时雨2
no:4	name:宋江4	nickName: 及时雨4
================打印链表——结束==================
节点 no:4	name:宋江4	nickName:及时雨4 已存在,无需重复添加
================打印链表——开始==================
no:1	name:宋江1	nickName: 及时雨1
no:2	name:宋江2	nickName: 及时雨2
no:3	name:宋江3	nickName: 及时雨3
no:4	name:宋江4	nickName: 及时雨4
no:5	name:宋江5	nickName: 及时雨5
no:6	name:宋江6	nickName: 及时雨6
================打印链表——结束==================
no为6的节点【no:6	name:宋江6	nickName:及时雨6】已更新为【no:6	name:宋江6-更新	nickName:及时雨6-更新】
================打印链表——开始==================
no:1	name:宋江1	nickName: 及时雨1
no:2	name:宋江2	nickName: 及时雨2
no:3	name:宋江3	nickName: 及时雨3
no:4	name:宋江4	nickName: 及时雨4
no:5	name:宋江5	nickName: 及时雨5
no:6	name:宋江6	nickName: 及时雨6
================打印链表——结束==================
不存在no为7的节点,无数据更新
================打印链表——开始==================
no:1	name:宋江1	nickName: 及时雨1
no:2	name:宋江2	nickName: 及时雨2
no:3	name:宋江3	nickName: 及时雨3
no:4	name:宋江4	nickName: 及时雨4
no:5	name:宋江5	nickName: 及时雨5
no:6	name:宋江6	nickName: 及时雨6
================打印链表——结束==================
no为5的节点已被删除
no为1的首节点已被移除
no为6的节点已被删除
不存在no为8的节点,无数据删除
================打印链表——开始==================
no:2	name:宋江2	nickName: 及时雨2
no:3	name:宋江3	nickName: 及时雨3
no:4	name:宋江4	nickName: 及时雨4
================打印链表——结束==================

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值