循环法
思想:循环将相邻两节点反向。
直接上图
看图所示,很明显循环的单位为
- 标记游标 pre、current、next
- 将当前节点指向前一节点(反转)
- 移动游标
- 重复以上步骤
解释:由于单链表无法从后一节点指向前一节点,故而需要保存前一节点(pre)用于反转的目标节点。
java代码实现
/**
* 链表反转
*/
private static void reverseLinked(Node head) {
Node pre = head;//第一步:标记游标
Node current = head.next;//第一步:标记游标
if (current == null) {
return;
}
Node next = current.next;//第一步:标记游标
current.next = pre;//第二步:节点反转
pre.next = null;
while (next != null) {
pre = current;//第三步:游标后移
current = next;
next = current.next;
current.next = pre;
}
}
看着有点重复代码,稍微改造一下吧:
/**
* 链表反转
*/
private static void reverse(Node node) {
Node pre = null;
Node next = null;
while (node != null) {
next = node.next;
node.next = pre;
pre = node;
node = next;
}
}
至此,反转结束,主要是通过标记循环节点,反转相邻节点,重复以上步骤。
递归法
迭代的思想在于
假设 分步 细化
假设DGreverse的作用就是将给定的链表反转成你想要的样子,然后你需要就是给方法传参。
假设链表就两个节点,则你需要做的就是这样
if (node == null || node.next == null) {
return node;
}
Node temp = node;//保存头节点
temp.next.next = node;//反转两节点
node.next = null;//头节点置为尾节点
然后将假设的部分用递归代替:
Node newNode = DGreverse(node.next);
最终就是下面这样。
java代码实现
/**
* 递归方式链表反转
*
* @param node
*/
private static Node DGreverse(Node node) {
if (node == null || node.next == null) {
return node;
}
Node temp = node;
Node newNode = DGreverse(node.next);
temp.next.next = node;
node.next = null;
return newNode;
}
完活后带个值验证一下。不要去想递归是怎么实现的,就假设已经实现了,然后传参实现、验证,done!