在具有多次出现值的链表中删除

时间:2014-08-18 09:45:48

标签: c data-structures linked-list singly-linked-list

  1. 我正在使用这段代码从链接列表中删除特定值,但是当我创建一个具有多次出现值的链表时。如果试图删除该值,它将进入无限循环。

  2. 但是当创建一个具有不同值的链表时,它可以正常工作。我该怎么办?

  3. 我的代码,

    struct link** delete(int value, struct link** head)
    {
        struct link* temp=*head;
        struct link* q;
        if(head==NULL)
        {
            printf("error");
        }
        else{
            while(temp->data!=value){
                q=temp;
                temp=temp->next;
            }
            q->next=temp->next;
            temp->next=NULL;
            free(temp);
            return head;
        }
    }
    

2 个答案:

答案 0 :(得分:1)

您的算法存在很多问题。包括但不限于......

  • 取消引用temp而不检查NULL。如果您在列表末尾并且temp落入NULL,则会出现未定义的行为。
  • 如果初始列表指针为NULL,则没有返回值。
  • 在检查{NULL}之前取消引用head

和其他人一样,但是......

使用指针指向您的优势,按地址链接查看列表。并且正确完成后,无需返回节点指针。即使受害者值恰好占据列表中的第一个节点,列表的头部也将根据需要正确更新。以下代码将删除列表中与特定值匹配的所有元素。如果列表已知 - 已排序,但现在可以提高效率:

void delete(int value, struct link** head)
{
    if (!head)
    {
        printf("error");
        return;
    }

    while (*head)
    {
        if ((*head)->data == value)
        {
            struct link *tmp = *head;
            *head = tmp->next;
            free(tmp);
        }
        else
        {
            head = &(*head)->next;
        }
    }
}

那就是它。上面代码中最重要的部分是如果要删除值,则不要将指针指针head推进到链中的下一个链接。相反,它连接当前节点(即将删除的节点)所在的下一个值。完成后,目标节点将成为孤立的"你可以安全地删除它。 *head自动引用要测试的下一个节点。


修改:仅针对单项清除的更新(在一般评论中看到)

void delete_one(int value, struct link** head)
{
    if (!head)
    {
        printf("error");
        return;
    }

    while (*head && (*head)->data != value)
        head = &(*head)->next;

    if (*head)
    {
        struct link *tmp = *head;
        *head = tmp->next;
        free(tmp);
    }
}

祝你好运

答案 1 :(得分:0)

该函数包含许多错误,并且具有未定义的行为。例如,如果head等于NULL,则不返回任何内容。如果第一个节点包含值,则变量q将是未初始化的。

我会按照以下方式编写函数

int delete( struct link **head, int value )
{
    int success = 0;
    if ( head == NULL ) return success;

    struct link *target = *head;
    struct link *prev = NULL;

    while ( target != NULL & target->data != value )
    {
        prev = target;
        target = target->next;
    }

    success = target != NULL;

    if ( success )
    {
        if ( prev == NULL )
        {
            *head = target->next;
        }
        else
        {
            prev->next = target->next;
        }
        free( target );
    }    

   return success;
}