【问题标题】:what does temp2->next contain?temp2->next 包含什么?
【发布时间】:2011-08-31 16:43:15
【问题描述】:

这是一个试图制作链表的程序。

#include <iostream>
using namespace std;

struct node {
char name[20];
int age;
int height;
node* next; // Pointer to the next node
 };
 node* startPTR = NULL; // Start Pointer (root)
                   // This pointer permanantly points to the start of the list
                   // Initially there are no nodes

void addNode_AT_END(); // prototype for the function that 'adds nodes at the end'

int main() {
   do {
 addNode_AT_END();
     cout << "Add more ?";
     char ch;
     cin >> ch;
   } while( ch == 'y');
}

void addNode_AT_END() {
node *temp1;
node *temp2;
temp1 = new node;  // We declare space for a pointer item and assign a temporary pointer to it  
                   //*temp1 is the node that it points to
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; // indicates that this node when inserted in the list will be the last node
  if( startPTR == NULL) {
    startPTR = temp1;  // In the empty list last node will be the first node
  }  else {
        temp2 = startPTR;
        while( temp2->next != NULL )
            temp2 = temp2->next;
        temp2->next = temp1;
     }

}

从这个尚未完成的程序中我可以理解:

如果第二次调用addNode_AT_END函数后的图为真,那么while( temp2-&gt;next != NULL )语句中的temp2-&gt;next包含什么?

【问题讨论】:

  • 有一个作业标签你知道;-)
  • @Suhail Gupta startPTR 不是指向 temp1,而是指向 temp1 指向的起始节点。因此,您的图表需要更正。
  • @EAGER_STUDENT 那么startPTR = temp1是什么意思呢?
  • @Suhail Gupta startPTR 是一个指针,你的图中 temp2 是如何指向 startPTR 的?
  • @ Nicolas Grebille 对于某些情况,我想介绍一个self satisfaction 标签

标签: c++ list visual-c++ pointers linked-list


【解决方案1】:

它包含NULL,那是因为这行:

temp1->next = NULL; 

每个新节点都有nextpointer,你通过上面的步骤使NULL,并且新节点附加在列表的末尾,因此,列表的末尾总是@ 987654325@。 while 循环遍历到列表的末尾,while(temp2-&gt;next != NULL) 设置条件,直到 temp2next 变为 NULL,执行 temp2 = temp2-&gt;next

【讨论】:

  • 之前每次将值设置为null,因此while循环不应该执行?!
【解决方案2】:

您的图表不正确。 start = temp2 确实意味着 start 和 temp2 指针都指向同一个节点。您的图表显示 temp2 指针的下一个字段包含 start 的地址。同样在执行start-&gt;next = temp1 之后并不意味着如果您在temp1 中获得了一些新节点值(在下一个函数调用中),start-&gt;next 仍将继续指向刚刚在temp1 中分配的新值。它将保留在您用新值覆盖之前的旧值。 start-&gt;next = temp1 只是复制temp1 中的值,即。变量(指针变量)的地址 start 指向的节点的下一个组件是 start-&gt;next 。之后 start 和temp1 之间就没有联系了。

在链表上下文中,“temp1 ----> temp2”是指地址存储在temp1中的节点的next字段,保存该节点的地址,该地址被持有或被持有temp2 。现在,在您更改指针变量temp2 的值后,不会更改保存在temp1 中存储的地址的节点的next 字段。 temp1-&gt;next 仍然包含它之前存储的值。

下一个链接不指向某个变量名,即start-&gt;next = temp 不会使start 节点的下一个节点总是指向temp1 包含的任何节点,但它start-&gt;next 将包含temp1 在分配时存储的地址。

注意,“start is pointing to temp1”表示地址

while (temp2->next != NULL)
  temp2 = temp2->next;

temp2-&gt;next = NULL 时会中断,这意味着temp2 指向列表的最后一个节点。此时temp2-&gt;next = temp1将新分配的节点链接到temp2当前指向的节点之后。这只是在末尾添加新节点。

  At the end of the above while loop

                                                              temp2
                                                                |
                                                                V

(start) ----> (n1) ----> (n2) ----> (n3) . . . (n(n-1)) ----> (nn) ----> NULL


   temp2->next = temp1    makes


                                                              temp2
                                                                |
                                                                V

(start) ----> (n1) ----> (n2) ----> (n3) . . . (n(n-1)) ----> (nn) ----> (temp1)--->NULL


 because temp2 holds the address of (nn) therefore linking the new node to the next node of the last node.

更新

第一次:

start = NULL
a new address is allocated and the address stored into temp1 pointer. Also temp->next = NULL
if condition becomes true and temp1 is assigned to start
start = temp1

List state


start = addr1;
 |
 V
(addr1) ----> (NULL)

第二次:

a new node is allocated and the address of the new node is stored into `temp1`. Let this address be `addr2`. Now `temp1` contains the value `addr2`

start is NOT NULL, as start has addr1 in it from the last call.So the else part is true and we get the address of the start node `addr1` into temp2.

temp2 = start;

which means temp2 now points to `addr1`

while loop is encountered. The first iteration the condition `temp2->next != NULL` is FALSE. This is because `temp2` points to `addr1` and the next pointer field of `addr1` has NULL from the last time the function is called. Therefore the while loop terminates.

The next statement does `temp2->next = temp1` . `temp2` points to `addr1` address, and the address of the newly allocated node `addr2` contained in `temp1` is assigned into the next field of the node whose address is stored into `temp2`. Which actually assigns the address `addr2` to the next field of the node identified by the address `addr1`.


temp1 = addr2     after allocation

start = addr1;
 |
 V
(addr1) ----> (NULL)      at begining
 ^
 |
 temp2


after temp2->next = temp1

start = addr1;
 |
 V
(addr1) ----> (addr2) ----> (NULL)      at end
 ^
 |
 temp2

第三次:

temp1 = addr3      new node address allocated

start = addr1;
 |
 V
(addr1) ----> (addr2) ----> (NULL)      at start
 ^
 |
 temp2


start = addr1;
 |
 V
(addr1) ----> (addr2) ----> (NULL)      next iteration after temp2=temp2->next
                 ^                      
                 |
               temp2


we can see temp2->next = NULL and while condition is false. Note that temp2 contains itself the address addr2, and thus temp2->next is NOT addr2, it is NULL.

start = addr1;
 |
 V
(addr1) ----> (addr2) ----> (NULL)      next iteration after temp2=temp2->next
                 ^                      
                 |
               temp2



After linking: temp2->next = temp1;

start = addr1;               temp1         the address addr3 (new node)
 |                             |          is stored in temp1. this address is assigned
 V                             V         to the next node of temp2, replacing NULL
(addr1) ----> (addr2) ----> (addr3) ----> (NULL)      
                 ^                      
                 |
               temp2

指针是遍历/遍历列表的方法。列表的起始地址保存在指针start 中。由于每个节点的next字段都指向下一个节点,如果我们得到start节点,那么我们可以通过依次跟踪next字段来访问每个节点。 temp1temp2 是用来完成遍历的指针,它们充当临时指针,temp1 用于保存新分配的节点,temp2 用于跟随@987654356 遍历列表@ 链接到最后一个,当找到最后一个链接时(通过下一个字段中的 NULL 指针检测到),这个最后一个节点的 NULL 链接被 temp1 持有的新分配的节点替换。由于现在temp1 持有的节点已链接/添加到列表的末尾,temp1 被重用于持有另一个新节点。

【讨论】:

  • @Code Monkey:只针对第一次迭代,之后新节点链接到头节点之后,从下一次调用进入while循环。
  • @downvoter:不胜感激。
  • 在我的回答中以粗体字阅读文本。 temp2-&gt;next = temp1 表示将当前存储在 temp1 的地址值复制到具有当前存储在 temp2 地址的节点的next 字段中.我会请你拿一份副本和一支笔(物理)并尝试追踪正在发生的事情。链接节点后,节点结构将保持不变,因为它们由每个节点的 next 字段保存。
  • @phoxis 谢谢!确实如此,为什么你用笔强调身体? !
  • @Suhail Gupta:大多数人在被要求涂鸦时会打开图像编辑器或文本编辑器。物理笔和纸仍然是草拟想法、理解事物和做笔记的最佳方式,我相信这一点。我很高兴知道您能够完成工作。
猜你喜欢
  • 2021-01-29
  • 1970-01-01
  • 2011-08-18
  • 2017-03-30
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-01
相关资源
最近更新 更多