我正在尝试将一个项目添加到链表的末尾,或者如果链表为空,则只添加一个项目。
到目前为止,我有
struct node* curr=head;
struct node* newnode=malloc(sizeof(struct node));
newnode->data=item;
newnode->next=NULL;
if (curr == NULL){
curr=newnode;
}
else {
while(curr->next == NULL){
curr=curr->next;
}
curr->next=newnode;
}
return 1;
那么代码看起来怎么样呢?如果能帮我们找出问题所在,我们将不胜感激。
这不适用于
if (curr == NULL){
curr=newnode;}
你需要这个:
if (curr == NULL){
head=newnode;}
它curr的方式是一个指向新元素的局部变量,并随着函数return而消失。你永远不会跟踪一个新的。
正如其他人所说,循环中需要!=
。
我能发现一件事看起来很奇怪
while(curr->next == NULL){
curr=curr->next;}
怀疑是否要转到下一个节点,但没有。您可能想要的是条件中的!=
,而不是==
while(curr->next == NULL)
应该是
while(curr->next != NULL)
需要进行一些更改:
在检查
curr == NULL
的情况下,您也需要更新头while循环应为
while (curr->next != NULL)
这不会有任何进展,你从开头开始,如果不是空的,那么你会说"继续前进,而下一个是空的"。如果next不是空的,你仍然会呆在最前面。
要在列表末尾添加,您需要以下内容:
else
{
while(curr->next != NULL) // keep going while curr->next is not null
{
curr = curr->next; // advance the pointer
}
// Here curr->next will definitely be null
curr->next = newnode; // now point curr->next to the new node
}
有人已经指出,在第一次检查中curr == NULL
的情况下,一旦完成赋值,就不会返回指针,头也永远不会初始化。
您可以通过在该函数的范围之外声明head
,或者在函数签名中有一个指向指针的指针来避免这种情况,例如:
int add_node(struct node** head) // I'll assume this is how you've declared your add function
// ^^ notice the pointer to pointer
{
struct node* curr = *head; // curr assignment changes slightly
struct node* newnode = malloc(sizeof(struct node));
newnode->data = item;
newnode->next = NULL;
if (curr == NULL)
{
*head = newnode; // this will dereference the pointer to the pointer and update head without returning anything
}
其余部分保持不变。
这可能是一个学习双指针习惯用法的好机会,它对于执行对链表的扫描修改非常有用。在你的情况下,那将是
struct node *newnode, **pnext;
newnode = malloc(sizeof *newnode);
newnode->data = item;
newnode->next = NULL;
for (pnext = &head; *pnext != NULL; pnext = &(*pnext)->next);
*pnext = newnode;
请注意,在这种方法中,您不再需要任何分支。无论您是在列表的开头、中间还是结尾添加新元素,它都能统一工作。