Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从单链表中删除元素_C_Algorithm_List_Pointers - Fatal编程技术网

C 从单链表中删除元素

C 从单链表中删除元素,c,algorithm,list,pointers,C,Algorithm,List,Pointers,我想从函数中的值指定的列表中删除一些元素。如果函数的“val”等于列表中的第一个元素,则我的函数不起作用。否则它工作得很好。有什么想法吗 struct elem { int val; struct elem *next; }; void del(struct elem *list, int val) { struct elem* tmp = list; struct elem* prev = NULL; while (tmp != NULL) {

我想从函数中的值指定的列表中删除一些元素。如果函数的“val”等于列表中的第一个元素,则我的函数不起作用。否则它工作得很好。有什么想法吗

struct elem {
    int val;
    struct elem *next;
};

void del(struct elem *list, int val) {
    struct elem* tmp = list;
    struct elem* prev = NULL;

    while (tmp != NULL) {
        if (tmp->val == val) {
            if (prev == NULL) {
                tmp = tmp->next;
                free(list);
                list = tmp;
            } else {
                prev->next = tmp->next;
                free(tmp);
                tmp = prev->next;
            }
        } else {
            prev = tmp;
            tmp = tmp->next;
        }
    }
}

调用函数无法知道
列表
已更新。它甚至会继续引用已被删除的相同的
列表。这不好

一种解决方案是将列表作为
struct elem**list
传递:

void del(struct elem **list, int val) {
    struct elem* tmp = *list;
    struct elem* prev = NULL;

    while (tmp != NULL) {
        if (tmp->val == val) {
            if (prev == NULL) {
                tmp = tmp->next;
                free(*list);
                *list = tmp;
            } else {
                prev->next = tmp->next;
                free(tmp);
                tmp = prev->next;
            }
        } else {
            prev = tmp;
            tmp = tmp->next;
        }
    }
}
编辑:还有其他解决方案。您可以返回新的列表指针:

struct elem *del(struct elem *list, int val) { ... }
你这样称呼它:

list = del(list, 12);
此解决方案的缺点是,
list
在调用中有些冗余,省略返回值是合法的,因此实际上不更新列表

我喜欢的解决方案是为列表定义一个控件结构。目前,它只包含头指针:

struct list {
    struct elem *head;
};
然后,在列表上操作的函数将指向此结构的指针作为参数:

void del(struct list *list, int val) {
    struct elem* tmp = list->head;
    struct elem* prev = NULL;

    while (tmp != NULL) {
        if (tmp->val == val) {
            if (prev == NULL) {
                tmp = tmp->next;
                free(list->head);
                list->head = tmp;
            } else {
                prev->next = tmp->next;
                free(tmp);
                tmp = prev->next;
            }
        } else {
            prev = tmp;
            tmp = tmp->next;
        }
    }
}

struct list
可以有其他字段,例如用于快速追加到末尾的尾部指针。您还可以跟踪列表长度。

您的调用函数无法知道列表已更新。它甚至会继续引用已被删除的相同的
列表。这不好

一种解决方案是将列表作为
struct elem**list
传递:

void del(struct elem **list, int val) {
    struct elem* tmp = *list;
    struct elem* prev = NULL;

    while (tmp != NULL) {
        if (tmp->val == val) {
            if (prev == NULL) {
                tmp = tmp->next;
                free(*list);
                *list = tmp;
            } else {
                prev->next = tmp->next;
                free(tmp);
                tmp = prev->next;
            }
        } else {
            prev = tmp;
            tmp = tmp->next;
        }
    }
}
编辑:还有其他解决方案。您可以返回新的列表指针:

struct elem *del(struct elem *list, int val) { ... }
你这样称呼它:

list = del(list, 12);
此解决方案的缺点是,
list
在调用中有些冗余,省略返回值是合法的,因此实际上不更新列表

我喜欢的解决方案是为列表定义一个控件结构。目前,它只包含头指针:

struct list {
    struct elem *head;
};
然后,在列表上操作的函数将指向此结构的指针作为参数:

void del(struct list *list, int val) {
    struct elem* tmp = list->head;
    struct elem* prev = NULL;

    while (tmp != NULL) {
        if (tmp->val == val) {
            if (prev == NULL) {
                tmp = tmp->next;
                free(list->head);
                list->head = tmp;
            } else {
                prev->next = tmp->next;
                free(tmp);
                tmp = prev->next;
            }
        } else {
            prev = tmp;
            tmp = tmp->next;
        }
    }
}

struct list
可以有其他字段,例如用于快速追加到末尾的尾部指针。您还可以跟踪列表长度。

因为您在
del()
中修改
list
,所以将其作为双指针传递。因为您在
del()
中修改
list
,将其作为双指针传递。@pospeq您可以在del函数中进行更改并返回
struct elem*
,这样就不需要双指针了。保持你的
head==list
在这里完好无损并重新运行head@pospeq:我添加了一些其他方法来实现同样的效果。我特别喜欢使用一个了解head的列表结构。@pospeq您可以在del函数中进行更改并返回
struct elem*
,这样就不需要双指针了。保持你的
head==list
在这里完好无损并重新运行head@pospeq:我添加了一些其他方法来实现同样的效果。我特别喜欢使用了解head的列表结构的方法。