20 Feb 2018
反转链表
一、题目
定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
二、解题思路
Notzuonotdied的思路
- 遍历。循环遍历,将下一个结点的指向前一个结点。
- 递归。
- 先保存当前结点cur和当前结点的下一个结点next。
- 将cur的指向下一个结点的对象[指针]设为空,next不变。
- 递归1,2过程,直到cur为空或者next为空。
- 递归返回,逐步将next的下一个结点设置为cur。
- 完成。(如果看不懂,请看下面代码的完整注释)
Kotlin实现
fun main(args: Array<String>) {
val root = initLinkList(6)
print(root)
print(reverseByLoop(root))
print(reverseByRecur(root))
}
/**
* 初始化单链表
*
* @return 返回单链表
* */
private fun initLinkList(length: Int): LinkNode? {
val root = LinkNode(0, null)
var temp: LinkNode = root
for (i in 1..(length - 1)) {
temp.next = LinkNode(i, null)
temp = temp.next!!
}
return root
}
/**
* 循环逆序
*
* @param root 头结点
* @return 返回逆序后的头结点
* */
private fun reverseByLoop(root: LinkNode?): LinkNode? {
if (root == null) return root
var pre = root
var cur = root.next
var next: LinkNode?
// 1 2 3 4 5
// pre cur next
while (cur != null) {
next = cur.next
cur.next = pre
pre = cur
cur = next
}
root.next = null
return pre
}
/**
* 递归反转
*
* @param current 当前结点
* @return 返回逆序后的头结点
*/
private fun reverseByRecur(current: LinkNode?): LinkNode? {
// 如果current为空,或者next结点为空,就直接返回
if (current?.next == null) return current
// 1 2 3 4 5
// cur next(保存cur,next结点)
// 1 2 3 4 5
// cur next(保存cur,next结点)
// 1 2 3 4 5
// cur next(保存cur,next结点)
// 1 2 3 4 5
// cur next(保存cur,next结点)
// 1 2 3 4 5
// cur next(保存cur,next结点)结束递归
// 1 2 3 4 5
// cur next(修改next.next = cur)
// 1 2 3 4 5
// cur next(修改next.next = cur)
// 1 2 3 4 5
// cur next(修改next.next = cur)
// 1 2 3 4 5
// cur next(修改next.next = cur)
// 1 2 3 4 5
// cur = null next(修改next.next = cur)
val nextNode = current.next
// 将结点独立,解除末尾循环指向的问题
current.next = null
// 递归,利用递归的特性将结点逆向指回上一个结点
val reverseRest = reverseByRecur(nextNode)
// 让下一个结点指向前一个结点
nextNode?.next = current
return reverseRest
}
输出结果
0 1 2 3 4 5
5 4 3 2 1 0
5 4 3 2 1 0
Til next time,
LinkWorld
at 12:54