链表中的指针

Pointers in linked lists

我目前正在研究列表(试图重新创建它们)并且遇到了一个奇怪的问题。这是我的结构:

struct listNode{
    listNode(int n, listNode* ne = NULL){
        value = n;
        next = ne;
    }
    int value;
    listNode* next;
};
listNode* head = NULL;

现在我做了一个在底部添加元素的函数:

void add(int n){
    if(head == NULL){
        head = new listNode(n);
        return;
    }
    listNode* n1 = head;
    while(n1 != NULL){ //Should be: while(n1->next != NULL){
        n1 = n1->next;
    }
    n1 = new listNode(n); //Should be: n1->next = new listNode(n);
}

但这并不是在头部添加任何元素。现在,我已经找到了解决方案(见上面的评论)我的问题是我不明白为什么我的第一个功能不起作用。
我将用一个方案来解释我的理解:

开始
头=空;

我加1
头 = [1, NULL];

我加2
while 循环到达最后一个元素(其中 "next" 为 NULL)并在其中创建新元素
HEAD = [1, new listNode(2)];
结果
HEAD = [1, 指针] [2, NULL];

现在,为什么 while 循环之后的 n1 不是我想要的?

很简单,

while(n1 != NULL){
    n1 = n1->next;
}

// n1 here is null
// head here is [1, NULL]

n1 = new listNode(n);

// n1 here is something
// head here is [1, NULL]

所以除非你将头的前一个元素的下一个指针设置为你的新元素,否则它将不起作用

您可以这样想:无论您过去在 while 循环中做什么,while 循环的条件是循环只会在 n1 变为null。所以,n1的值在循环后保证是null

但是,while 循环后 n1 的值无关紧要,因为您在 while 循环后没有使用它。

另一方面,您的最后一条指令是 n1 = new listNode(n);,因此您要创建一个新的 listNode,并将其分配给 n1,然后您会因为离开该函数而永远忘记它。 (所以,新节点被泄露了。)

函数不起作用,因为 n1 是函数的局部变量。变量的任何变化都不会影响列表的其他节点。

您应该更改列表的原始节点。函数可以这样写

void add( int value )
{
    listNode **node = &head;

    while ( *node ) node = &( *node )->next;

    *node = new listNode( value );
}

在这种情况下,因为变量 node 指向列表的实际字段,所以它确实更改了它们。