近期有学习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
================打印链表——结束==================