diff --git a/kotlin/06_linkedlist/SinglyLinkedList.kt b/kotlin/06_linkedlist/SinglyLinkedList.kt new file mode 100644 index 0000000..35fcec2 --- /dev/null +++ b/kotlin/06_linkedlist/SinglyLinkedList.kt @@ -0,0 +1,293 @@ +/** + * 1)单链表的插入、删除、查找操作; + * 2)链表中存储的是int类型的数据; + * + * Author:Zackratos + */ + +class SinglyLinkedList { + + private var head: Node? = null + + companion object { + @JvmStatic + fun main(args: Array) { + + 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?) +} \ No newline at end of file