递归
# 经典的代码贴上
def reverse_list(self, head):
if not head or not head.next: # not head 是为了防止空列表;
return head
newH = self.reverse_list(head.next) # 一直为5,因为是新链表表头
head.next.next = head
head.next = None # 因为是递归,只执行了5->4操作,但是这时候4仍然指向5,所以需要去掉这个指向;在从前往后的迭代中,类似操作是cur = cur.next
return newH
理解:
拿题目举例,[1->2->3->4->5] -> [5->4->3->2->1]
1.递归到head=4时,self.reverse_list得到newH为5;
2.head.next.next = head,(一个next表示指向下一个)所以实质上是5->4;
3.head.next = None表示断开原来4指向5的箭头(4—>None);
4.依次循环,但每一次都是返回的都是新链表的头5,所以返回的值都是newH;
非递归
# 同样经典代码贴上
def reverse_list(self, head):
# 题目说了是反转链表的头结点,所以不能再建一个dummy
# dummy = ListNode(None)
# dummy.next = head
cur, pre = head, None
while cur:
cur.next, pre, cur = pre, cur, cur.next
return prex
理解:
同样对于None->1->2->3->4->5
1.pre指向None, cur指向1
2.cur下移一位指向2(cur.next),pre同样下移一位指向1(cur),再让2(cur.next)指向1(pre)
只是上面经典代码是利用的python多变量赋值才能这么简洁,如果分开写要注意两点:
1)、(cur.next)指向(pre)要在cur(当前指向1)下移一位指向cur.next(指向2) 之后; 因为如果先让(cur.next)指向(pre),这样先刷新了cur.next值,导致指针再无法取后面的值了
2)、2(cur.next)指向1(pre)这一步要发生在pre下移一位指向1(cur)之后,否则如果是下面的顺序:
cur = cur.next(cur指针由1移到2)
cur.next = pre (2->None即2的下一个是None)
pre = cur (pre指针移到1)
最终是None->1->2->None,形成了环
不用python的多变量赋值代码:
a = cur.next
cur.next = pre
pre = cur
cur = a
ps:
python的多变量赋值:
如上图,3个变量同时赋值时,虽然cur进行了更新,但是pre拿到的是cur更新前的值;cur_next也是拿的pre更新前的值;可见python多变量赋值涉及同一变量传值与更新时,往往先传值后更新;并且python变量赋值是指新变量指向原变量的指针对象,与原变量更新无影响