删除链表中的节点

时间:2018-09-23 12:18:16

标签: c linked-list

我刚开始进入节点和简单的链表。虽然我发现链接列表令人困惑,但我仍然开始对它们有所了解,并且可以按照不同的教程进行编码。

但是为了删除节点,我尝试了一段不太奏效的代码,然后又找到了一个。除了我不太明白为什么一个有效而另一个无效。

这是行不通的:

void remove_character(Character **head)
{
Character *current=*head,
    *temp=malloc(sizeof(Character));//temporary node to 
     //remove node
char *name=malloc(100);

if(current!=NULL)//if there is at least one node
{
    printf("Enter name: ");
    scanf("%s", name);
}

if(!strcmp(name, (*head)->name))//removes head and 
//makes next node head
{
    temp=(*head);
    (*head)=(*head)->next;
    free(temp->name);
    free(temp);
    current=*head;
}

while(current!=NULL)
{
       if(!strcmp(name, current->name))
    {
        temp=current;//assign node to be removed
        current=current->next;//move to next node
        free(temp->name);
        free(temp);//free removed node
    }
    current=current->next;
}
}

但这可行:

void remove_character(Character **head)
{
Character *current=*head, 
  *temp=malloc(sizeof(Character));
char *name=malloc(100);

if(current!=NULL)
{
    printf("Enter name: ");
    scanf("%s", name);
}

if(!strcmp(name, (*head)->name))
{
    temp=(*head);
    (*head)=(*head)->next;
    free(temp->name);
    free(temp);
    current=*head;
}

while(current!=NULL)
{
    if(current->next!=NULL)
    {
        if(!strcmp(name, current->next->name))
        {//if next node is node to be removed
            temp=current->next;
            current->next=current->next->next;
                            //moves to next node
            free(temp->name);
            free(temp);
        }
    }
    current=current->next;
}
}

基本上,第二个节点预期一个节点并进一步链接一个节点,但是为什么这个节点而不是另一个节点起作用(这会在已删除节点所在的位置显示分段错误...节点看起来很容易,但管理起来却很复杂。尤其是当您无法想象其工作原理时。

1 个答案:

答案 0 :(得分:1)

在第一种方法中,您并不主动。

也就是说,您在访问特定的string之后检查node,一旦找到要删除的node,只需free,然后不修正list就可以继续前进。

再添加一个pointer来指向前一个node应该可以解决此问题。

        if(!strcmp(name, (*head)->name))
        {
            /* Code to delete in the head node */ 

            temp=(*head);
            (*head)=(*head)->next;
            free(temp->name);
            free(temp);
            current=*head;
        }
        else 
        {

            /* Code to delete in the rest of the list*/ 
            character *prev=*head;
            while(current!=NULL)
            {
                if(!strcmp(name, current->name))
                {
                    prev->next = current->next;//move to next node
                    free(current->name);
                    free(current);//free removed node
                    break;
                }
                prev = current;
                current=current->next;
            }
        }

在第二种方法中,您很主动。

也就是说,您在访问特定的string之前先检查node,一旦发现要删除的下一个node,那么您free并在固定list之后继续移动。

if(!strcmp(name, current->next->name))   // Found out next node to be deleted
{
     temp=current->next;                 // Get the next node
     current->next=current->next->next;  // Adjust the list by skipping the next node

     free(temp->name);                   // Free the node.
     free(temp);
}