从单链表中删除元素
Delete elements from singly linked list
我想从函数中的值指定的列表中删除一些元素。如果函数的 '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;
}
}
}
您的调用函数无法知道 list
已更新。它甚至会继续引用已被删除的同一个 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;
}
}
}
编辑:还有其他解决方案。您可以 return 新列表指针:
struct elem *del(struct elem *list, int val) { ... }
你这样称呼它:
list = del(list, 12);
这个解决方案的缺点是 list
在调用中有些多余,并且省略 return 值是合法的,因此实际上不会更新列表。
我喜欢的一个解决方案是为您的列表定义一个控制结构。目前,它只包含头指针:
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
可以有额外的字段,例如用于快速附加到末尾的尾指针。您还可以跟踪列表长度。
我想从函数中的值指定的列表中删除一些元素。如果函数的 '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;
}
}
}
您的调用函数无法知道 list
已更新。它甚至会继续引用已被删除的同一个 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;
}
}
}
编辑:还有其他解决方案。您可以 return 新列表指针:
struct elem *del(struct elem *list, int val) { ... }
你这样称呼它:
list = del(list, 12);
这个解决方案的缺点是 list
在调用中有些多余,并且省略 return 值是合法的,因此实际上不会更新列表。
我喜欢的一个解决方案是为您的列表定义一个控制结构。目前,它只包含头指针:
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
可以有额外的字段,例如用于快速附加到末尾的尾指针。您还可以跟踪列表长度。