菜鸡刚学完防止忘了所以mark在这,说的都是大白话,觉得不够专业的话,可以看原博客:
https://lyl0724.github.io/2020/01/25/1/
原答案:
1 public ListNode swapPairs(ListNode head) {
2 //终止条件:链表只剩一个节点或者没节点了,没得交换了。
3 //返回的是已经处理好的链表
4 if(head == null || head.next == null){
5 return head;
6 }
7 //一共三个节点:head, next, swapPairs(next.next)
8 //下面的任务便是交换这3个节点中的前两个节点
9 ListNode end = head.next;
10 head.next = swapPairs(end.next);
11 end.next = head;
12 //根据第二步:返回给上一级的是当前已经完成交换后,
13 //即处理好了的链表部分
14 return end;
15 }
以下是个人的理解
假如有一个链表 1 -> 2 -> 3 -> 4
进入执行:
此时head为1,执行到第9行,将head节点指向的节点地址赋给end(即2)
进入第一次迭代:
此时head为3,执行到第9行,将head节点指向的节点地址赋给end(即4)
进入第二次迭代:
此时head为空,进入if语句,返回head给上一级
返回第一次迭代:
10行:将空地址赋值给节点head(即3)的next指针域,
11行:把head节点赋给end节点(即4)的next指针域 (这两行交换了节点指向的位置 head原本指向end改为head指向后面的节点(即空)end节点原本指向后面的结点(空)改为指向head ,此时链表变成了 4- > 3 -> 空 )
12行:返回end节点(即4)(个人理解:由于链表的数据结构在存储空间不连续,用next指针链接,所以返回最前面的节点就等于返回后面的一整串,即4- > 3 -> 空 )
返回最开始的执行:
10行:将返回的节点(即4)赋值给节点head(即1)的next指针域,
11行:把head节点赋给end节点(即2)的next指针域 (这两行交换位置 此时链表变成了 2 -> 1 -> 4- > 3 -> 空 )
12行:返回end节点(即2 ,相当于2 -> 1 -> 4- > 3 -> 空 )
结束
大功告成,看了一上午终于看懂了 哭