参考:链表翻转的图文讲解(递归与迭代两种实现) https://blog.youkuaiyun.com/fx677588/article/details/72357389
单链表反转的两种实现(Java) https://blog.youkuaiyun.com/acquaintanceship/article/details/73011169
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
方法1,遍历法 非递归
1)实际上是引用变量的处理(类似于指针)
ListNode pre=null; //对链表设置一前一后两个节点
ListNode then=null;
2) then=head.next;//暂存head下一个地址,防止变化指针指向后找不到后续的数
3)head.next=pre;//head.next指向前一个空间
4) pre=head;//新链表的头移动到head,扩长一步链表
5) head=then; //head指向原始链表head指向的下一个空间
then=head.next;//暂存head下一个地址,防止变化指针指向后找不到后续的数
head.next=pre;//head.next指向前一个空间
pre=head;//新链表的头移动到head,扩长一步链表
head=then; //head指向原始链表head指向的下一个空间
代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null){链表为空或者仅1个数直接返回
return head;
}
ListNode pre=null; //对链表设置两个节点
ListNode then=null;
while(head!=null){
then=head.next;//暂存head下一个地址,防止变化指针指向后找不到后续的数
head.next=pre;//head.next指向前一个空间
pre=head;//新链表的头移动到head,扩长一步链表
head=then; //head指向原始链表head指向的下一个空间
}
return pre;
}
}
2,递归方式
递归法会逐层确定该节点有没有next节点,若为空,则认定递归到最深层元素。同时将该层节点的next指向父节点,在递归栈中以此类推。
//递归法会逐层确定该节点有没有next节点,若为空,则认定递归到最深层元素。同时将该层节点的next指向父节点,在递归栈中以此类推。
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null){//链表为空直接返回,而H.next为空是递归基
return head;
}else{
ListNode newHead= reverseList(head.next); //一直循环到链尾
head.next.next=head; //翻转链表的指向
//head的下一个节点指向head
//如果注释掉head.next=null; 1、2号节点闭环问题。由于1号节点的next没有置空,依旧指向2号节
//点,所以遍历时候肯定存在环。
head.next=null; //记得赋值NULL,防止链表错乱,
return newHead;
}
}
}
注意:
else{ ListNode newHead= reverseList(head.next);
head.next.next=head;
head.next=null;
return newHead;}
}
方法reverseList(head.next)只有一个return 语句返回head,下一层方法迭代的head与本方法的head要注意区分。
所以下一层迭代方法中的return head 仅仅影响当前方法的newHead节点,不影响当前方法的head节点。
注意,最后要返回头节点。
头节点只有一个。
参考:https://blog.youkuaiyun.com/lucky52529/article/details/84672526的图解