仅将节点表示为数字对理解算法没有多大帮助。 head、second 和 reverse 必须是节点引用,并且函数的每个递归调用都有其自己的不同变量集——即使它们的名称与另一个调用中的名称相同。
为了获得更好的洞察力,假设每个变量都有一个数字后缀,以便根据定义它们的执行上下文来区分它们。因此顶级调用将具有head1、second1、reverse1、并且第一个递归调用将有自己的head2、second2、reverse2、...等。
让我们可视化second 初始化时的列表:
head1 second1
↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ value: 2 │ │ value: 3 │ │ value: 4 │
│ next: ———————→ │ next: ———————→ │ next: ———————→ │ next:None │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
现在进行递归调用,将引用传递给第二个节点。在递归执行上下文中,这个引用被命名为head,我们也得到了一个新的second引用:
head2 second2
↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ value: 2 │ │ value: 3 │ │ value: 4 │
│ next: ———————→ │ next: ———————→ │ next: ———————→ │ next:None │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
在下一个递归执行上下文中分配了一组类似的变量:
head3 second3
↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ value: 2 │ │ value: 3 │ │ value: 4 │
│ next: ———————→ │ next: ———————→ │ next: ———————→ │ next:None │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
最深的递归调用将有它的head 引用最后一个节点:
head4
↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ value: 2 │ │ value: 3 │ │ value: 4 │
│ next: ———————→ │ next: ———————→ │ next: ———————→ │ next:None │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
这个最深的调用返回head。调用者(有自己的变量集)将该返回值分配给reverse
reverse3 = head4
head3 second3
↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ value: 2 │ │ value: 3 │ │ value: 4 │
│ next: ———————→ │ next: ———————→ │ next: ———————→ │ next:None │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
然后second.next = head 和head.next = None 被执行:
reverse3
head3 second3
↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ value: 2 │ │ value: 3 │ │ value: 4 │
│ next: ———————→ │ next: ———————→ │ next: None│ ←——————— :next │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
本次调用结束,返回reverse给调用者。调用者有自己的变量,并将返回的引用分配给他们的reverse 变量:
head2 second2 reverse2 = reverse3
↓ ↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ value: 2 │ │ value: 3 │ │ value: 4 │
│ next: ———————→ │ next: ———————→ │ next: None│ ←——————— :next │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
然后second.next = head 和head.next = None 被执行:
head2 second2 reverse2
↓ ↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ value: 2 │ │ value: 3 │ │ value: 4 │
│ next: ———————→ │ next: None│ ←——————— :next │ ←——————— :next │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
本次调用结束,返回reverse给调用者。调用者有自己的变量,并将返回的引用分配给他们的reverse 变量:
head1 second1 reverse1 = reverse2
↓ ↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ value: 2 │ │ value: 3 │ │ value: 4 │
│ next: ———————→ │ next: None│ ←——————— :next │ ←——————— :next │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
然后second.next = head 和head.next = None 被执行:
head1 second1 reverse1
↓ ↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 1 │ │ value: 2 │ │ value: 3 │ │ value: 4 │
│ next: None│ ←——————— :next │ ←——————— :next │ ←——————— :next │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
本次调用结束,返回reverse给调用者。这确实是完全颠倒名单的新掌门人。