思路:所谓反转链表就是指将这个链表的所有指针方向反向。
采取的办法是时刻保留连续的3个结点,ppre/pcur/pnext;
修改指针方向:将pcur.next设置为ppre;
然后修改ppre/pcur/pnext向前推进即可
ppre=pcur;
pcur=pnext;
pnext=pnext.next;
需要注意的是:
1. 输入的链表head==null;
2. 输入的链表只有一个结点,直接返回head
3. 当pnext==null时,就要停止,因为此时pnext.next是非法的,空指针异常,应该停止然后手动完成最后一次指针反向pcur.next设置为ppre。
/*
publicclass ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
//所谓反转链表即将整个链表的指针反向,所谓输出链表的所有元素即为输出链表的头结点
publicclass Solution {
public ListNode ReverseList(ListNode head){
//定义三个属性,记录连续的3个结点
ListNode ppre=null;
ListNode pcur=head;
if(head==null){
//输入空结点
return null;
}
ListNode pnext=head.next;
if(pnext==null){
//输入的链表只有一个结点
returnhead;
}
while(pnext!=null){
//修改指针方向
pcur.next=ppre;
//修改ppre/pcur/pnext
ppre=pcur;
pcur=pnext;
pnext=pnext.next;
}
pcur.next=ppre;
return pcur;
}
}
常识:注意几个问题:在Java中,对象确实都是引用传递的,但是其实引用符号在栈中,对象以及属性在堆中,在栈中可以引用堆中的对象,但是堆中是不可以引用栈中的变量的,因为这样引用一个符号是没有意义的,所以即使有时候堆中属性指向了一个引用符号,例如head.next=ppre;其本质上还是将ppre指向的对象赋值给了head.next,即堆与堆中属性的修改会导致对象引用堆中的某个其他对象,栈中的符号只是一个中转变量而已,所以堆中变量只会在堆中相互引用。
pcur.next=ppre;
ppre=pcur;
pcur=pnext;
pnext=pnext.next;
这个赋值过程从引用上来看很复杂,其实没有必要这么复杂,把他当做非引用传递即可,即可以当做是直接进行的值传递。后面的语句不会受到上面语句变化的影响。