我有以下代码来反转链表。我在while循环中感到困惑,所以如果有人可以提供有关其实际工作方式的直观解释,我一定会感激不尽。
static void Reverse (struct node** headRef)
{
struct node* result = NULL;
struct node* current = *headref;
struct node* next;
while(current != NULL)
{
next = current->next;
current->next = result;
result = current;
current = next;
}
*headRef = result;
}
答案 0 :(得分:11)
好的,这是我试图让valya的答案更清晰(尽管我认为它已经相当不错了):
说我们有这个清单:
// a->b->c->d->e->NULL
我们从第一个节点a
开始,该节点包含指向next
的指针b
:
// a->b ...
第next = current->next;
行将next
设置为b
(足够简单)。下一行current->next = result;
执行此操作:
// NULL<-a b ... (notice there is no longer a pointer from a to b)
然后我们result = current;
将result
设置为a
(再次,足够简单)。最后,我们拥有所有重要的current = next;
,将current
设置为b
。
因此,在while循环的下一次迭代中,next
设置为b
,result
设置为a
,current
设置为{{ 1}},我们重新开始:
b
然后我们再做一次:
next = current->next;
// NULL<-a<-b c ...
current->next = result;
result = current;
一旦我们到达链表中的最后一项(本例中为next = current->next;
// NULL<-a<-b<-c d ...
current->next = result;
result = current;
),就会发生这种情况:
e
现在,因为next = current->next; // next becomes NULL
// NULL<-a<-b<-c<-d<-e
current->next = result;
result = current; // result is now e
current = next; // current is now NULL
为NULL,while循环终止,我们留下:
current
正如您现在所看到的那样,*headRef = result;
指向headRef
,将e
视为链接列表中的新第一项,e
指向{ {1}},e->next
指向d
等。
答案 1 :(得分:3)
我用dot制作了一个图表,我认为它将以图形方式解释正在发生的事情:
如果有人关心的话,这是(草率)点源:
digraph g {
label = "Start"
subgraph cluster_1
{
a1 -> b1 -> c1;
current1 -> a1;
result1
a1 [label="a"]
b1 [label="b"]
c1 [label="c"]
current1 [label="current"]
result1 [label="result"]
}
label = "Once through loop"
subgraph cluster_2
{
current2 -> b2;
result2 -> a2;
b2 -> c2;
a2 [label="a"]
b2 [label="b"]
c2 [label="c"]
current2 [label="current"]
result2 [label="result"]
}
label = "Twice through loop"
subgraph cluster_3
{
current3 -> c3;
result3 -> b3;
b3 -> a3;
a3 [label="a"]
b3 [label="b"]
c3 [label="c"]
current3 [label="current"]
result3 [label="result"]
}
label = "Final"
subgraph cluster_4
{
result4 -> c4 -> b4 -> a4;
a4 [label="a"]
b4 [label="b"]
c4 [label="c"]
current4 [label="current"]
result4 [label="result"]
}
label = ""
}
答案 2 :(得分:2)
答案 3 :(得分:1)
列表看起来像:
=>(1) => => => => => => => => =>(10)
我们颠倒了列表的每一部分
<=(1) => => => => => => => => =>(10)
<=(1) <= => => => => => => => =>(10)
<=(1) <= <= => => => => => => =>(10)
...
<=(1) <= <= <= <= <= <= <= <= <=(10)
所以,现在开始到底,我们可以从不同的角度查看列表,看看:
=>(10) => => => => => => => => =>(1)
答案 4 :(得分:-2)
有关详细说明,请参阅here。以下是摘录:
public class List {
private class Node {
int data;
Node next;
}
private Node head;
public void reverse() {
if (head == null) return;
Node prev = null,curr = head,next = null;
while (curr != null) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
head = prev;
}
}
The list:
==========
1->2->3->4->5
------------------------------------------------------------------
Running of the code:
============================
At start:
**********
head = 1;
prev = null,curr = 1, next = null
1st iteration of while loop:
******************************
next = 2;
2->3->4->5
curr.next = null;
1->null
prev = 1;
1->null
curr = 2;
2->3->4->5
2nd iteration of while loop:
******************************
next = 3
3->4->5
curr.next = 1
2->1->null
prev = 2
2->1->null
curr = 3
3->4->5
3rd iteration of while loop:
******************************
next = 4
4->5
curr.next = 2
3->2->1->null
prev = 3
3->2->1->null
curr = 4
4->5
4th iteration of while loop:
******************************
next = 5
5->null
curr.next = 3
4->3->2->1->null
prev = 4
4->3->2->1->null
curr = 5
5->null
5th iteration of while loop:
******************************
next = null
null
curr.next = 4
5->4->3->2->1->null
prev = 5
5->4->3->2->1->null
curr = null
There is no 6th iteration and the while loop terminates since
curr is null and the check is for curr != null.
last statement:
==================
head = prev
This statement leaves the list reversed with referencing head with the reversed node prev
to become the new head node.