更改链接列表中的节点

时间:2015-05-24 22:36:22

标签: c list linked-list

这有点令人难以置信

我会试着解释我的怀疑。

检查此功能,例如:

void snoc(Lint *l, int val){
    Lint i, new;

    new = (Lint) malloc(sizeof(Nodo));
    new->value = val;
    new->next = NULL;

    i=(*l);

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

    i->next = new;
}

我理解背后的概念,我在使用列表时没有遇到任何问题,考虑到我无法使用列表初始指针本身迭代列表(如果我这样做,我会丢失初始指针)< / p>

问题是,i=(*l)然后使用i = i-&gt;继续遍历列表,使i变量不断变化。

在这个特定的例子中,原始列表不会改变,直到我找到链接列表的结尾,然后我做出归属和vo!我在最后插入一个元素。

我的疑问是,如果通过更改i,并在最后制作i->next = new,这并不意味着每次我制作i=i->next时,都要更改原始节点中的所有节点列出?

另一个例子是init:

void init (Lint *l){
    Lint i, prev;
    i=(*l);
    prev=NULL;

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

如果我这样做,通过在适当的时候将i->next更改为NULL,将删除最后一个元素。但在此之前,我已经通过告诉i

再次对i=i->next本身进行了更改

如果我要对(*l)本身进行此更改(通过执行(*l)=(*l)->next),我将破坏原始列表。

我真的希望你们能理解我的怀疑。

3 个答案:

答案 0 :(得分:2)

是的,我们确实理解您的困惑,而且它来自于没有在那张纸上编制列表指针,因此您可以想象正在发生的事情。在处理node链接问题时始终使用图表。例如,对于您的单链接列表,当前节点名为i(可疑的名称选择)和您的新节点new一个有用的图表将是:

Singly Linked-List (non-circular)

         Tail                 Current                Head
      (list start)               i                   new
     +------------+        +------------+        +------------+
     |   Payload  |        |   Payload  |        |   Payload  |
     +------------+        +------------+        +------------+
     |   Next     |------->|   Next     |------->|   Next     |--->NULL   
     +------------+        +------------+        +------------+        

现在,我打赌你可以告诉我们:

  

更改i,并在结尾处制作i->next = new

会这样做。这不是一个挖掘或意味着居高临下,它实际上是您需要解决链接列表问题的方式,直到您完成它足以可视化您脑中的指针布线。当您进行循环或双向链接列表插入和删除时,这一点更为重要。无论出现什么问题,如果你只是把它写下来并标记所有正在建立或断开的连接,你就可以在编辑器中干净地编码。

答案 1 :(得分:1)

对一些未成年人进行修改,您的代码就像这样

void snoc(Lint *l, int val)
{
   Lint i, new;
   new = (Lint) malloc(sizeof(Nodo));
   new->value = val;
   new->next = NULL;
   i = *l;  
   if(!(*l))
   {
     *l = new;
     return;
   }
   while(i->next) i = i->next;   // (1)
   i->next = new;                // (2)
}

,这就是它的解释:

在(1)中,我们遍历链表直到结束。我们知道我们已经结束了,因为i->next(在每个循环步骤之后指向下一个nodo项目)是null,所以在这种情况下,我们使i->next指向新创建的nodo项目(2 )。但是l在函数期间从未改变,l总是指向链表的开头,所以这个函数的目的是在最后添加一个新元素而不改变{{1}的值}}。

但我们也可以使用此功能初始化链接列表...例如:

l

(0)检查 Lint l = NULL; snoc(&l, 10); // l will be initialized with a new nodo item with 10 as the value its value member 是否为空,在这种情况下,我们使l指向新分配的nodo项并返回...所以初始化完成。

我为上面的代码添加了另一种方法

*l

答案 2 :(得分:0)

我不确定我理解你的问题,但为什么不简单地复制指针呢?您可以保留指向初始元素的指针,并使用第二个元素遍历它。

相关问题