C - 从单链表中删除一个元素
C - delete an element from singly linked list
我想不通问题出在哪里,
为什么 del 函数没有按预期工作?
#include<stdio.h>
#include<malloc.h>
typedef struct list List;
struct list
{
int data;
List* next;
};
void prl(List* head);
void ins(List** head, int value);
void del(List** head, int value);
int main()
{
List* head = NULL;
ins(&head, 10);
ins(&head, 50);
ins(&head, 20);
ins(&head, 150);
ins(&head, 120);
del(&head, 150);
prl(head);
//freeing dynamically allocated memory for each nodes
while(head!=NULL)
{
List* t = head;
head = head->next;
free(t);
}
return 0;
}
void prl(List* head)
{
if(head == NULL)
printf("List is empty\n");
else
{
while(head != NULL)
{
printf("%d ", head->data);
head = head->next;
}
}
}
void ins(List** head, int value)
{
List* node = malloc(sizeof *node);
node->data = value;
node->next = NULL;
node->next =*head;
*head = node;
}
void del(List** head, int value)
{
List* p,*q;
p=q=*head;
if((*head)->data == value)
{
*head = (*head)->next;
free(p);
return;
}
else
{
while(p->next != NULL)
{
if(p->data == value)
{
q->next = p->next;
free(p);
}
else
{
q = p;
p = p->next;
}
} // while loop ends
} // outer else ends
} // del function ends
在 运行 之后,输出为空白,我认为 del 函数外部 else 循环内部(逻辑上)有问题,但是可以使用此函数删除第一个值。
我认为你没有在此处添加 return 语句:
if(p->data == value)
{
q->next = p->next;
free(p);
return;
}
尽管我发表了评论,但我还是决定帮助你。
让我们看看这些行:
while(p->next != NULL)
{
if(p->data == value)
{
q->next = p->next;
free(p);
}
else
{
// Irrelevant...
}
}
假设循环内的条件 p->data == value
恰好为真,那么会发生什么?你让 q->next
指向 p->next
,这可能没问题,然后你继续循环而不让 p
指向其他任何地方。
当循环继续时 p
指向您刚刚调用 free
的数据,因此取消引用 p
例如p->next
在循环条件中会导致 未定义的行为.
解决方案是适当更新 p
和 q
。
while(p->next != NULL) {
if(p->data == value) {
q->next = p->next;
free(p);
} else {
q = p->link; //here....
p = p->next;
}
}
我想不通问题出在哪里,
为什么 del 函数没有按预期工作?
#include<stdio.h>
#include<malloc.h>
typedef struct list List;
struct list
{
int data;
List* next;
};
void prl(List* head);
void ins(List** head, int value);
void del(List** head, int value);
int main()
{
List* head = NULL;
ins(&head, 10);
ins(&head, 50);
ins(&head, 20);
ins(&head, 150);
ins(&head, 120);
del(&head, 150);
prl(head);
//freeing dynamically allocated memory for each nodes
while(head!=NULL)
{
List* t = head;
head = head->next;
free(t);
}
return 0;
}
void prl(List* head)
{
if(head == NULL)
printf("List is empty\n");
else
{
while(head != NULL)
{
printf("%d ", head->data);
head = head->next;
}
}
}
void ins(List** head, int value)
{
List* node = malloc(sizeof *node);
node->data = value;
node->next = NULL;
node->next =*head;
*head = node;
}
void del(List** head, int value)
{
List* p,*q;
p=q=*head;
if((*head)->data == value)
{
*head = (*head)->next;
free(p);
return;
}
else
{
while(p->next != NULL)
{
if(p->data == value)
{
q->next = p->next;
free(p);
}
else
{
q = p;
p = p->next;
}
} // while loop ends
} // outer else ends
} // del function ends
在 运行 之后,输出为空白,我认为 del 函数外部 else 循环内部(逻辑上)有问题,但是可以使用此函数删除第一个值。
我认为你没有在此处添加 return 语句:
if(p->data == value)
{
q->next = p->next;
free(p);
return;
}
尽管我发表了评论,但我还是决定帮助你。
让我们看看这些行:
while(p->next != NULL)
{
if(p->data == value)
{
q->next = p->next;
free(p);
}
else
{
// Irrelevant...
}
}
假设循环内的条件 p->data == value
恰好为真,那么会发生什么?你让 q->next
指向 p->next
,这可能没问题,然后你继续循环而不让 p
指向其他任何地方。
当循环继续时 p
指向您刚刚调用 free
的数据,因此取消引用 p
例如p->next
在循环条件中会导致 未定义的行为.
解决方案是适当更新 p
和 q
。
while(p->next != NULL) {
if(p->data == value) {
q->next = p->next;
free(p);
} else {
q = p->link; //here....
p = p->next;
}
}