293 lines
6.6 KiB
Kotlin
293 lines
6.6 KiB
Kotlin
|
/**
|
|||
|
* 1)单链表的插入、删除、查找操作;
|
|||
|
* 2)链表中存储的是int类型的数据;
|
|||
|
*
|
|||
|
* Author:Zackratos
|
|||
|
*/
|
|||
|
|
|||
|
class SinglyLinkedList {
|
|||
|
|
|||
|
private var head: Node? = null
|
|||
|
|
|||
|
companion object {
|
|||
|
@JvmStatic
|
|||
|
fun main(args: Array<String>) {
|
|||
|
|
|||
|
val link = SinglyLinkedList()
|
|||
|
println("hello")
|
|||
|
val data = intArrayOf(1, 2, 5, 3, 1)
|
|||
|
|
|||
|
for (i in data.indices) {
|
|||
|
//link.insertToHead(data[i]);
|
|||
|
link.insertTail(data[i])
|
|||
|
}
|
|||
|
|
|||
|
println("打印原始:")
|
|||
|
link.printAll()
|
|||
|
if (link.palindrome()) {
|
|||
|
println("回文")
|
|||
|
} else {
|
|||
|
println("不是回文")
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
fun findByValue(value: Int): Node? {
|
|||
|
var p = head
|
|||
|
while (p != null && p.data != value) {
|
|||
|
p = p.next
|
|||
|
}
|
|||
|
|
|||
|
return p
|
|||
|
}
|
|||
|
|
|||
|
fun findByIndex(index: Int): Node? {
|
|||
|
var p = head
|
|||
|
var pos = 0
|
|||
|
while (p != null && pos != index) {
|
|||
|
p = p.next
|
|||
|
++pos
|
|||
|
}
|
|||
|
|
|||
|
return p
|
|||
|
}
|
|||
|
|
|||
|
//无头结点
|
|||
|
//表头部插入
|
|||
|
//这种操作将于输入的顺序相反,逆序
|
|||
|
fun insertToHead(value: Int) {
|
|||
|
val newNode = Node(value, null)
|
|||
|
insertToHead(newNode)
|
|||
|
}
|
|||
|
|
|||
|
fun insertToHead(newNode: Node) {
|
|||
|
if (head == null) {
|
|||
|
head = newNode
|
|||
|
} else {
|
|||
|
newNode.next = head
|
|||
|
head = newNode
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//顺序插入
|
|||
|
//链表尾部插入
|
|||
|
fun insertTail(value: Int) {
|
|||
|
|
|||
|
val newNode = Node(value, null)
|
|||
|
//空链表,可以插入新节点作为head,也可以不操作
|
|||
|
if (head == null) {
|
|||
|
head = newNode
|
|||
|
|
|||
|
} else {
|
|||
|
var q = head
|
|||
|
while (q?.next != null) {
|
|||
|
q = q.next
|
|||
|
}
|
|||
|
newNode.next = q?.next
|
|||
|
q?.next = newNode
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
fun insertAfter(p: Node?, value: Int) {
|
|||
|
val newNode = Node(value, null)
|
|||
|
insertAfter(p, newNode)
|
|||
|
}
|
|||
|
|
|||
|
fun insertAfter(p: Node?, newNode: Node) {
|
|||
|
if (p == null) return
|
|||
|
|
|||
|
newNode.next = p.next
|
|||
|
p.next = newNode
|
|||
|
}
|
|||
|
|
|||
|
fun insertBefore(p: Node?, value: Int) {
|
|||
|
val newNode = Node(value, null)
|
|||
|
insertBefore(p, newNode)
|
|||
|
}
|
|||
|
|
|||
|
fun insertBefore(p: Node?, newNode: Node) {
|
|||
|
if (p == null) return
|
|||
|
if (head === p) {
|
|||
|
insertToHead(newNode)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
var q = head
|
|||
|
while (q != null && q.next !== p) {
|
|||
|
q = q.next
|
|||
|
}
|
|||
|
|
|||
|
if (q == null) {
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
newNode.next = p
|
|||
|
q.next = newNode
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
fun deleteByNode(p: Node?) {
|
|||
|
if (p == null || head == null) return
|
|||
|
|
|||
|
if (p === head) {
|
|||
|
head = head?.next
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
var q = head
|
|||
|
while (q != null && q.next !== p) {
|
|||
|
q = q.next
|
|||
|
}
|
|||
|
|
|||
|
if (q == null) {
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
q.next = q.next?.next
|
|||
|
}
|
|||
|
|
|||
|
fun deleteByValue(value: Int) {
|
|||
|
if (head == null) return
|
|||
|
|
|||
|
var p = head
|
|||
|
var q: Node? = null
|
|||
|
while (p != null && p.data != value) {
|
|||
|
q = p
|
|||
|
p = p.next
|
|||
|
}
|
|||
|
|
|||
|
if (p == null) return
|
|||
|
|
|||
|
if (q == null) {
|
|||
|
head = head?.next
|
|||
|
} else {
|
|||
|
q.next = q.next?.next
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
fun printAll() {
|
|||
|
var p = head
|
|||
|
while (p != null) {
|
|||
|
print("${p.data} ")
|
|||
|
p = p.next
|
|||
|
}
|
|||
|
println()
|
|||
|
}
|
|||
|
|
|||
|
//判断true or false
|
|||
|
fun TFResult(left: Node?, right: Node?): Boolean {
|
|||
|
var l: Node? = left
|
|||
|
var r: Node? = right
|
|||
|
|
|||
|
println("left_:${l?.data}")
|
|||
|
println("right_:${r?.data}")
|
|||
|
while (l != null && r != null) {
|
|||
|
if (l.data == r.data) {
|
|||
|
l = l.next
|
|||
|
r = r.next
|
|||
|
continue
|
|||
|
} else {
|
|||
|
break
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
println("什么结果")
|
|||
|
return l == null && r == null
|
|||
|
}
|
|||
|
|
|||
|
// 判断是否为回文
|
|||
|
fun palindrome(): Boolean {
|
|||
|
if (head == null) {
|
|||
|
return false
|
|||
|
} else {
|
|||
|
println("开始执行找到中间节点")
|
|||
|
var p = head
|
|||
|
var q = head
|
|||
|
if (p?.next == null) {
|
|||
|
println("只有一个元素")
|
|||
|
return true
|
|||
|
}
|
|||
|
while (q?.next != null && q.next?.next != null) {
|
|||
|
p = p?.next
|
|||
|
q = q.next?.next
|
|||
|
}
|
|||
|
|
|||
|
println("中间节点${p?.data}")
|
|||
|
println("开始执行奇数节点的回文判断")
|
|||
|
val leftLink: Node?
|
|||
|
val rightLink: Node?
|
|||
|
if (q?.next == null) {
|
|||
|
// p 一定为整个链表的中点,且节点数目为奇数
|
|||
|
rightLink = p?.next
|
|||
|
leftLink = inverseLinkList(p)?.next
|
|||
|
println("左边第一个节点${leftLink?.data}")
|
|||
|
println("右边第一个节点${rightLink?.data}")
|
|||
|
|
|||
|
} else {
|
|||
|
//p q 均为中点
|
|||
|
rightLink = p?.next
|
|||
|
leftLink = inverseLinkList(p)
|
|||
|
}
|
|||
|
return TFResult(leftLink, rightLink)
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//带结点的链表翻转
|
|||
|
fun inverseLinkList_head(p: Node): Node {
|
|||
|
// Head 为新建的一个头结点
|
|||
|
val Head = Node(9999, null)
|
|||
|
// p 为原来整个链表的头结点,现在Head指向 整个链表
|
|||
|
Head.next = p
|
|||
|
/*
|
|||
|
带头结点的链表翻转等价于
|
|||
|
从第二个元素开始重新头插法建立链表
|
|||
|
*/
|
|||
|
var Cur = p.next
|
|||
|
p.next = null
|
|||
|
var next: Node?
|
|||
|
|
|||
|
while (Cur != null) {
|
|||
|
next = Cur.next
|
|||
|
Cur.next = Head.next
|
|||
|
Head.next = Cur
|
|||
|
println("first " + Head.data)
|
|||
|
|
|||
|
Cur = next
|
|||
|
}
|
|||
|
|
|||
|
// 返回左半部分的中点之前的那个节点
|
|||
|
// 从此处开始同步像两边比较
|
|||
|
return Head
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//无头结点的链表翻转
|
|||
|
fun inverseLinkList(p: Node?): Node? {
|
|||
|
|
|||
|
var pre: Node? = null
|
|||
|
var r = head
|
|||
|
println("z---${r?.data}")
|
|||
|
var next: Node?
|
|||
|
while (r !== p) {
|
|||
|
next = r?.next
|
|||
|
|
|||
|
r?.next = pre
|
|||
|
pre = r
|
|||
|
r = next
|
|||
|
}
|
|||
|
|
|||
|
r?.next = pre
|
|||
|
// 返回左半部分的中点之前的那个节点
|
|||
|
// 从此处开始同步像两边比较
|
|||
|
return r
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
fun createNode(value: Int): Node = Node(value, null)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
class Node(var data: Int, var next: Node?)
|
|||
|
}
|