C - 从单链表中删除元素

时间:2017-02-02 13:55:24

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

我无法找出问题所在,

为什么del函数没有按预期工作?

#include<stdio.h>
#include<malloc.h>

typedef struct list List;

struct list
{
    int data;
    List* next;
};

void prl(List* head);
void ins(List** head, int value);
void del(List** head, int value);

int main()
{
    List* head = NULL;

    ins(&head, 10);
    ins(&head, 50);
    ins(&head, 20);
    ins(&head, 150);
    ins(&head, 120);

    del(&head, 150);

    prl(head);

    //freeing dynamically allocated memory for each nodes

    while(head!=NULL)
    {
        List* t = head;
        head = head->next;
        free(t);
    }

    return 0;
}

void prl(List* head)
{
    if(head == NULL)
        printf("List is empty\n");
    else
    {
        while(head != NULL)
        {
            printf("%d ", head->data);
            head = head->next;
        }
     }
}

void ins(List** head, int value)
{
    List* node = malloc(sizeof *node);

    node->data = value;
    node->next = NULL;

    node->next =*head;
    *head = node;

}


void del(List** head, int value)
{
    List* p,*q;
    p=q=*head;

    if((*head)->data == value)
    {
        *head = (*head)->next;
        free(p);
        return;
    }
    else
    {
        while(p->next != NULL)
        {
            if(p->data == value)
            {
                q->next = p->next;
                free(p);
            }
            else
            {
                q = p;
                p = p->next;
             }
        } // while loop ends

    } // outer else ends

} // del function ends

运行之后,输出为空,我认为del函数外部其他循环中的某些(逻辑上)是错误的,但是可以使用此函数删除第一个值。

3 个答案:

答案 0 :(得分:2)

尽管我的评论,我还是决定帮助你。

让我们来看看这些内容:

while(p->next != NULL)
{
    if(p->data == value)
    {
        q->next = p->next;
        free(p);
    }
    else
    {
        // Irrelevant...
    }
}

让我们说循环中的条件p->data == value恰好是真的,那么会发生什么?您将q->next指向p->next,这可能没问题,然后您继续循环而不会在其他地方点p点。

当循环继续时p指向您刚刚调用free的数据,因此将p取消引用,例如循环条件中的p->next将导致未定义的行为

解决方案是适当更新pq

答案 1 :(得分:1)

我认为你没有在这里添加一个return语句:

if(p->data == value)
    {
        q->next = p->next;
        free(p);
        return;
    }

答案 2 :(得分:0)

while(p->next != NULL) { 
  if(p->data == value) { 
    q->next = p->next; 
    free(p); 
  } else { 
    q = p->link; //here.... 
    p = p->next; 
  }
}