[英]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;
}
}
}
編輯 :還有其他解決方案。 您可以返回新的列表指針:
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
可以具有其他字段,例如用於快速附加到末尾的尾部指針。 您還可以跟蹤列表的長度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.