我有一个如下的循环链表,它保存了要处理的数据的状态。状态用于决定从列表中删除可能位于开头,中间或结尾的状态。该列表有时甚至可能没有任何数据,或者可能有多个要删除的节点。
struct data
{
bool status;
char other_info[20];
struct data *next;
};
我尝试了以下代码
struct data* delete_nodes(struct data *head)
{
struct data* first = NULL, *prev = NULL, *temp = NULL;
first = head;
temp = head;
prev = head;
do
{
//prev = temp;
if (temp != NULL && temp->next == head)
{
head->next = NULL;
free(temp);
head = NULL;
return head;
}
if (temp != NULL && temp->status == true)
{
//temp = prev;
prev->next = temp->next;
free(temp);
temp = prev->next;
}
else if(temp != NULL)
temp = temp->next;
if (temp == NULL)
return head;
} while (temp != NULL && first != temp);
head = temp;
return head;
}
现在,将数据推入其中工作正常。如果只有一个节点,删除也可以正常工作。但是当有多个节点被删除时,它会崩溃。
delete_nodes()
函数由一个处理数据的线程调用(如果存在)并调用delete_nodes()
答案 0 :(得分:0)
以下声明导致问题
prev->next = temp->next; // what is prev here ?
应该是
if (temp != NULL && temp->next !=NULL && temp->status == true) {
prev = temp;//current node which you want to delete
temp->next = prev->next;//this statement should be done before next statement..current node next should be prev node next
prev->next = temp->next;//
free(temp);
temp = prev->next;
}
答案 1 :(得分:0)
此代码块
if (temp != NULL && temp->status == true)
{
//temp = prev;
prev->next = temp->next;
free(temp);
temp = prev->next;
}
在进行第一次迭代时,肯定是错误的。
在第一次迭代prev
和temp
都与head
相同。所以prev
指向的内存与free
- ing。
考虑放弃NULL
的所有检查,并且只在开始时进行检查,即
struct data* delete_nodes(struct data *head)
{
if (head == NULL) return NULL;
// Hereafter no further checks for NULL is needed
完整的功能可能如下所示:
struct data* delete_nodes(struct data *head)
{
if (head == NULL) return NULL;
struct data *prev = NULL;
struct data *temp = head;
struct data *first = head;
do
{
struct data *next = temp->next;
if (temp->status)
{
if (prev == NULL)
{
// Delete head element
head = temp->next;
}
else
{
// Delete middle element
prev->next = temp->next;
}
free(temp);
}
else
{
prev = temp;
}
temp = next;
} while (temp != first);
if (prev == NULL)
{
// List is empty
return NULL;
}
return head;
}