我正在使用这段代码从链接列表中删除特定值,但是当我创建一个具有多次出现值的链表时。如果试图删除该值,它将进入无限循环。
但是当创建一个具有不同值的链表时,它可以正常工作。我该怎么办?
我的代码,
struct link** delete(int value, struct link** head)
{
struct link* temp=*head;
struct link* q;
if(head==NULL)
{
printf("error");
}
else{
while(temp->data!=value){
q=temp;
temp=temp->next;
}
q->next=temp->next;
temp->next=NULL;
free(temp);
return head;
}
}
答案 0 :(得分:1)
您的算法存在很多问题。包括但不限于......
temp
而不检查NULL。如果您在列表末尾并且temp
落入NULL,则会出现未定义的行为。head
。和其他人一样,但是......
使用指针指向您的优势,按地址链接查看列表。并且正确完成后,无需返回节点指针。即使受害者值恰好占据列表中的第一个节点,列表的头部也将根据需要正确更新。以下代码将删除列表中与特定值匹配的所有元素。如果列表已知 - 已排序,但现在可以提高效率:
void delete(int value, struct link** head)
{
if (!head)
{
printf("error");
return;
}
while (*head)
{
if ((*head)->data == value)
{
struct link *tmp = *head;
*head = tmp->next;
free(tmp);
}
else
{
head = &(*head)->next;
}
}
}
那就是它。上面代码中最重要的部分是如果要删除值,则不要将指针指针head
推进到链中的下一个链接。相反,它连接当前节点(即将删除的节点)所在的下一个值。完成后,目标节点将成为孤立的"你可以安全地删除它。 *head
自动引用要测试的下一个节点。
修改:仅针对单项清除的更新(在一般评论中看到)
void delete_one(int value, struct link** head)
{
if (!head)
{
printf("error");
return;
}
while (*head && (*head)->data != value)
head = &(*head)->next;
if (*head)
{
struct link *tmp = *head;
*head = tmp->next;
free(tmp);
}
}
祝你好运
答案 1 :(得分:0)
该函数包含许多错误,并且具有未定义的行为。例如,如果head等于NULL,则不返回任何内容。如果第一个节点包含值,则变量q将是未初始化的。
我会按照以下方式编写函数
int delete( struct link **head, int value )
{
int success = 0;
if ( head == NULL ) return success;
struct link *target = *head;
struct link *prev = NULL;
while ( target != NULL & target->data != value )
{
prev = target;
target = target->next;
}
success = target != NULL;
if ( success )
{
if ( prev == NULL )
{
*head = target->next;
}
else
{
prev->next = target->next;
}
free( target );
}
return success;
}