【问题标题】:Pointers in linked lists链表中的指针
【发布时间】:2015-11-29 20:28:22
【问题描述】:

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

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);
}

但这并没有在头部添加任何元素。现在,我已经找到了解决方案(参见上面的 cmets)我的问题是我不明白为什么我的第一个函数不起作用。
我会用一个方案来解释我所理解的:

开始
头=空;

我加 1
HEAD = [1, NULL];

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

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

【问题讨论】:

  • 永远不要将问题命名为“指针如何工作?”。标题应该与 LinkedLists 相关
  • @asimes 真的不知道该写什么,抱歉。无论如何,沉默的投票者,愿意解释吗?
  • 假设你有int n = 5; int m = n; m = 7。你认为n 应该变成 7 吗?不要这么想。但尽管如此,您说n1 = n1->next; n1 = new listNode(n); 并期望先前n1next 成员发生变化。很奇怪吧?
  • @n.m.如果n1 = n1->next; n1 之后为空,我希望它指向新元素
  • 那么你应该将新元素分配给最后一个元素的属性next。在说“但是 n1 最后一个元素的属性next”之前,再看一下m = n; m = 7。您是否将 7 分配给 n

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


【解决方案1】:

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

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

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

【讨论】:

  • 正确,减去“不久后收集的垃圾”。这是 C++,它被泄露了。
  • 但是如果最后一个值为 null 为什么通过更改它(因为它是由 n1->next 获得的)它不会影响 head 的下一个?
【解决方案2】:

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

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

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

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

    *node = new listNode( value );
}

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

【讨论】:

  • 我明白了,所以我只是复制了“next”属性,通过编辑副本,原件不会受到影响,对吧?
【解决方案3】:

很简单,

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]

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

【讨论】:

  • 如果n1 不是头的下一个,那么这个存储在哪里?
  • n1 永远丢失了,你不将它分配给可恢复的东西,它会变成内存泄漏
  • 但是n1不是最后一个元素的属性“next”吗?
  • 不,只要你说n1 = n1->next n1 为空,不再等于头部
  • n1 = n1->next 在整个while循环中都是有效的,除了最后,最后一个元素指向null,你现在明白了吗?
猜你喜欢
  • 1970-01-01
  • 2012-08-11
  • 1970-01-01
  • 2018-07-28
  • 1970-01-01
  • 2020-01-22
  • 2013-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多