无法使用c中的循环链表中的条件删除节点
Can't delete a node using a condition in circular linked list in c
我有一个如下的循环链表,它保存了待处理数据的状态。 status 用于决定从列表中删除,可以是开头、中间或结尾。该列表有时甚至可能根本没有任何数据,或者可能有多个节点要删除。
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()
以下语句导致了问题
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;
}
这个代码块
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;
}
我有一个如下的循环链表,它保存了待处理数据的状态。 status 用于决定从列表中删除,可以是开头、中间或结尾。该列表有时甚至可能根本没有任何数据,或者可能有多个节点要删除。
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()
以下语句导致了问题
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;
}
这个代码块
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;
}