删除链接列表中具有特定值的所有节点

标题非常自我解释。 这是我为此目的编写的函数:

void wipeLoneCells() { cell *tmp; tail = head; while (1) { if (head == tail && !tail->flag) { head = head->next; free(tail); tail = head; continue; } tmp = tail->next; /***/ if (tmp->next == NULL && !tmp->flag) { tail->next = NULL; free(tmp); break; } else if (!tmp->flag) { tail->next = tmp->next; free(tmp); continue; } tail = tail->next; } } 

列表的头部和尾部是全局的,列表是在调用此函数时构建的,其中头部指向第一个节点,尾部指向最后一个节点(其下一个为NULL)。 我几乎可以肯定我的链表是正确构建的,因为我可以打印它们而没有错误。 有时此function可以正常工作,有时会导致标记为星星的线路出现访问冲突。 我知道这并不是完全错误的,因为当我没有产生错误时我得到了我想要的结果,虽然我经常得到错误所以必须有一些我忽略的东西。 预先感谢您的任何帮助。

编辑:这是固定代码:

 void wipeLoneCells() { cell *tmp; tail = head; while (1) { if (head == tail && !tail->flag) { head = head->next; free(tail); tail = head; continue; } tmp = tail->next; if (tmp->next == NULL && !tmp->flag) { tail->next = NULL; free(tmp); break; } else if (tmp->next == NULL) { tail = tmp; break; } else if (!tmp->flag) { tail->next = tmp->next; free(tmp); continue; } tail = tail->next; } } 

如果

 tmp = tail->next; 

NULL ? 下一行尝试取消引用NULL指针,这会导致未定义的行为 – 可能导致崩溃。

您应检查此情况并采取适当的措施。

单链表中正确的deleteitem()应如下所示:

您可以避免递归并提出迭代版本(试一试,但如果您需要帮助,请告诉我)。 我不会在这种情况下使用一段while(1)

 typedef struct node { int data; struct node *next; }NODE; /* (1) deleting head delete element and adjust head pointer (2) deleting tail delete element and adjust tail pointer (3) one element list if data is the data for the only element then delete the list and set head and tail pointers to NULL (4) all the other cases traverse through the list and hold the previous pointer. delete element and adjust the next pointers. (5) if not the above cases, then element not present.. do nothing.. */ void deleteitem(int data) { printf("%s: %d - ", __FUNCTION__, data); NODE *cur = head; NODE *prev = cur; NODE *temp = NULL; if (head == NULL) { assert (tail == NULL); printf("Empty list \n"); return; } if (head->data == data) { temp = head; // one element list if (head == tail) head = tail = NULL; else // list has more than one element head = head->next; printf("%d \n", temp->data); free(temp); deleteitem(data); return; } while (cur != NULL) { if (cur->data == data) { if (cur == tail) { tail = prev; } prev->next = cur->next; printf(" %d deleted\n", cur->data); free(cur); assert(tail->next == NULL); deleteitem(data); return; } prev =cur; cur = cur->next; } printf(" %d not found\n", data); return; }