问题描述
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
解题思路(头插法):
我们要想实现的反转并不仅仅是数据的移位,而是涉及到结点的移动,所以我们无法使用数组。
我们都知道,头插法得到的链表序列与插入的顺序刚好相反,因此我们可以采取这样的办法来解决这个问题。
头插法即每次将插入的结点插入到链表的第一个位置,比如我们插入1,2,3,4.那么第1次插入1,第二次将2插入到1的前面,第3次将3插入在2的前面,第4次将4插入3的前面。
1.先定义一个节点reverseHead =new HeroNode();
2.从头到尾遍历原来的链表,每遍历一一个节点,就将其取出,并放在新的链表reverseHead的最前端.
3.原来的链表的head.next = reverseHead.next
代码实现:
本题思路非常简单,但是实现起来却处处有坑,博主调试了很久才成功。
public ListNode reverseList(ListNode head) {
//如果当前链表为空,或者只有一个结点,无需反转,直接返回
if(head==null || head.next==null){
return head;
}
//定义一个辅助的指针(变量),帮助我们遍历原来的链表
ListNode cur=head;
//这个变量很重要,指向当前结点的下一个结点,否则你移走当前结点的时候,整个链表就断掉了
ListNode next=null;
ListNode reverseHead=new ListNode(-1); //头结点
reverseHead.next=null;
//遍历原来的链表,每遍历一个结点,就将其取出,并放在新的链表的最前端
while(cur!=null){
//首先要保留cur的下面一个结点。因为后面需要使用
next=cur.next;
cur.next=reverseHead.next; //将cur的下一个结点指向新的链表最前端
reverseHead.next=cur;
//这里面只能是cur=next,而不能是cur=cur.next,因为我们已经修改cur.next到新的链表中去了
cur=next;
}
return reverseHead.next;
}
总结:
本题关键点1:要使用next指针,next指针非常重要,指向当前结点的下一个结点,否则你移走当前结点的时候,整个链表就断掉了。在我们进行遍历的过程中,我们会让cur.next指向reverseHead.next,此时cur后面的链就都断开了,所以我们需要在移动cur指针之前,保存好cur.next。
本题关键点2:cur后移不再是cur=cur.next,而是cur=next,因为我们已经改动过了cur.next指针了。