c - 我不明白为什么我不能像这样在末尾添加节点

标签 c list struct linked-list

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

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

最佳答案

该函数的实现存在两个问题。

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

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

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

关于c - 我不明白为什么我不能像这样在末尾添加节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59462521/

相关文章:

CCS PICC CCP 设置

c - 在C函数中返回struct

c - 如何获取 DRAM 地址而不是虚拟地址

c - 等待播放完成

c++ - 是否可以强制 CMake 在其他项目类型生成时生成 Visual Studio 项目?

java - 如果将泛型类型变量用作类中的字段,它是否应该包含 <T> 表达式?

java - set.remove 与 list.remove (函数绑定(bind))

c - 在 C 中释放指向链表的双指针

c - Eclipse CDT 内容协助未完成结构

generics - 枚举通用结构