这是一段试图构建链表的代码。
struct node {
char name[20];
int age;
int height;
node* next; // Pointer to the next node
};
node* startPTR = NULL;
void addNode_AT_END() {
node *temp1;
node *temp2;
temp1 = new node;
cout << "Enter the name : ";
cin >> temp1->name;
cout << endl << "Enter the age : ";
cin >> temp1->age;
cout << endl << "Enter height : ";
cin >> temp1->height;
temp1->next = NULL;
if( startPTR == NULL) {
startPTR = temp1;
} else {
temp2 = startPTR;
while( temp2->next != NULL )
temp2 = temp2->next;
temp2->next = temp1;
}
}
以下是对上述函数进行两次背靠背调用后的图。
start = addr1;
|
V
(addr1) ----> (addr2) ----> (NULL) at end
^
|
temp2
,其中addr1和addr2分别是第一个和第二个节点的地址。
第三次调用之后会发生什么?第三次调用的迭代将如何进行?我无法理解list
在第二次呼叫后是如何连接的。照我所说,一切所建立的,直到我知道,都要归于无有。那么,list将如何进一步发展?在第三次调用期间节点是如何放置的?
这就是奇迹发生的地方:
1. temp2 = startPTR;
2. while( temp2->next != NULL )
3. temp2 = temp2->next;
4. temp2->next = temp1;
首先,temp2
将指向列表的开头。在第2行和第3行中,您将temp2
更改为下一个节点,直到到达temp2->next
为NULL
的节点。该节点是列表的最后一个节点,与列表的大小无关。
最后,在第4行中,将temp2->next
更改为temp1
,因此现在它指向新节点(即最后一个节点现在指向新节点)。temp1->next
也是NULL
,所以temp1
现在代表列表的末尾。
第一行之后是
start = addr1;
|
V
(addr1) ----> (addr2) ----> (NULL)
^
|
temp2
temp2->next
不是NULL
(它是addr2),所以你迭代并执行第3行,你得到:
start = addr1;
|
V
(addr1) ----> (addr2) ----> (NULL)
^
|
temp2
temp2->next
现在是NULL
。停止循环,执行第4行,得到:
start = addr1;
|
V
(addr1) ----> (addr2) ----> (addr3) ----> (NULL)
^ ^
| |
temp2 temp1
注释:你知道指针是怎么工作的吗?想象一下:您有一个节点,它是内存中的一些数据。当内存中有变量时,这些变量有地址。假设addr1为10,addr2为150,addr3(即new
ed节点)为60。start
的取值为10。因此,"指向"列表的第一个节点(即使用此地址,您可以访问其数据)。其中一个数据是next
字段。第一个节点的next
字段的值为150,因此指向下一个节点。当你说temp2 = start
时,你把数字10放在temp2
中,此时temp2->next
的值是150。当您说temp2=temp2->next
时,您只需将值150放在temp2
中,覆盖之前的值。通过这种方式,您已经有效地将指针从指向第一个节点移动到现在指向第二个节点。现在的temp2->next
是NULL
(也就是0),现在的temp2->next=temp1
,就是在temp2
的next
字段里放了值60。现在temp2->next
是60。temp2->next->next
是NULL
这很简单。while循环将把temp2移动到最后一个元素。然后,您创建的由temp1指向的节点被分配为temp2的下一个节点
我不明白你在烦什么。在任何调用过程中,while()循环将遍历列表中的所有节点,直到到达末尾,然后将最后一个节点的指针设置为新分配的节点(temp1)。
temp1和temp2是指针。它们不存储节点的数据,而是将地址存储在存储数据的内存中。因此,在第一次迭代结束时,在startPTR = temp1
之后,startPTR指向temp1指向的同一地址。temp1是否仍然存在并不重要,因为现在startPTR指向该节点。在第二次调用结束时,temp2->next=temp1
(此时temp2==startPTR)使节点的next
字段指向新分配的temp1