【问题标题】:I can't understant why I can't add a node at the end like this我不明白为什么我不能像这样在最后添加一个节点
【发布时间】:2020-04-15 04:01:05
【问题描述】:

我正在尝试在列表末尾插入一个新节点。我知道第一种方法是“正确的方法”。 但是我正在尝试使用另一个函数(第二个函数)的另一种方法,但我的列表似乎没有变化,有什么想法吗?

typedef struct listnode *listptr;

struct listnode {
    int value;
    listptr next;
};

void insert_at_end(listptr *x, int n) {
    while ((*x) != NULL) {       
        x = &((*x)->next);   
    }                       
    *x = (listptr)malloc(sizeof(struct listnode));  
    (*x)->next = NULL;   
    (*x)->value = n;    
}

void insert_at_end_2(listptr x, int n) {
    listptr newnode = (struct listnode *)malloc(sizeof(struct listnode));
    newnode->next = NULL;
    newnode->value = n;

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

【问题讨论】:

  • x 是一个局部变量。更改它对调用者的变量没有影响。
  • 仅供参考,insert_at_end_2malloc(sizeof(listptr)) 是错误的。它应该是malloc(sizeof *x)malloc(sizeof(struct listnode))。孩子们,这就是为什么在 typedef 别名中隐藏指针类型是一个糟糕的主意。或许,该函数实际上 return 是什么?你忽略了那条相当重要的信息。无关,don't cast malloc in C progams
  • 我编辑了你注意到的原始代码就像你说的那样
  • @averageJoe 太好了,现在看看 Kaylums cmets。这是第一版和第二版的区别。

标签: c list struct linked-list


【解决方案1】:

这个函数实现有两个问题。

第一个是函数处理作为参数传递给函数的原始节点的副本。因此更改副本不会影响原始参数。

第二个问题是在这个循环之后

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

x 将等于 NULL。所以下一条语句

x =newnode;

不改变最后一个节点的数据成员next。所以列表不会改变。

在头节点不通过引用传递的情况下使用该方法,函数实现可以如下所示。

listptr insert_at_end_2( listptr x, int n )
{
    listptr newnode = malloc( sizeof( *listptr ) );

    if ( newnode != NULL )
    {
        newnode->next = NULL;
        newnode->value = n;

        if ( x == NULL )
        {
            x = newnode;
        }
        else
        {
            listptr current = x;

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

    return x;
} 

但是,当头节点通过引用传递时,此实现和第一个实现一样有一个缺点:该函数不报告是否成功分配了新节点。

所以一个更好的函数实现看起来像

int insert_at_end( listptr *x, int n )
{
    listptr newnode = malloc( sizeof( *listptr ) );

    int success = newnode != NULL;

    if ( success )
    {
        newnode->next  = NULL;   
        newnode->value = n;

        while ( *x != NULL )
        {       
            x = &( *x )->next;   
        }                       

        *x = newnode;
    }

    return success;  
}

【讨论】:

    【解决方案2】:

    来自莫斯科的@Vlad 我让你的代码和我的相似。所以这行得通。

    
    void insert_at_end_2( listptr x, int n )
    {
      listptr newnode =  (listptr)malloc( sizeof( listptr ) );
      newnode->next = NULL;
      newnode->value = n;
    
    
      while ( x->next!= NULL )
      {
          x = x->next;
      }
      x->next  = newnode;
    
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-06
      • 1970-01-01
      • 2013-07-23
      • 1970-01-01
      相关资源
      最近更新 更多