嘿,请有人清楚我的疑问,如果我删除一个节点,后来我尝试打印该节点的数据应该是什么输出?如何检查节点是否被删除?
在这个程序中,我试图删除重复的节点以及如何知道我是否正确删除它们!我想删除一个节点后,如果我尝试访问该删除的节点的数据,如果一切正常,我将得到零!但这就是这种情况,所以我再次尝试计算节点,这很好。计算唯一的检查方法吗?
#include <stdio.h>
#include <stdlib.h>
typedef struct dll {
int data;
struct dll* next;
} dll;
int main() {
dll* p1, *p2, *p3, *p4, *p5, *temp, *head, *todel, *cur, *fwd, *dup;
int count = 0, i = 0, j = 0;
p1 = (dll*)malloc(sizeof(dll));
p2 = (dll*)malloc(sizeof(dll));
p3 = (dll*)malloc(sizeof(dll));
p4 = (dll*)malloc(sizeof(dll));
p5 = (dll*)malloc(sizeof(dll));
p1->data = 1;
p1->next = p2;
p2->data = 2;
p2->next = p3;
p3->data = 3;
p3->next = p4;
p4->data = 2;
p4->next = p5;
p5->data = 1;
p5->next = NULL;
head = p1;
printf("p1::%p\n", p1);
printf("p2::%p\n", p2);
printf("p3::%p\n", p3);
printf("p4::%p\n", p4);
printf("p5::%p\n", p5);
printf("head::%p\n", head);
for (temp = head; temp != NULL; temp = temp->next) {
count++;
}
printf("no of nodes %d\n", count);
temp = head;
cur = temp;
while (cur) {
for (fwd = cur->next; fwd != NULL; fwd = fwd->next) {
if (cur->data == fwd->data) {
cur->next = fwd->next;
// fwd->next=fwd->next->next;
todel = fwd;
free(todel);
fwd = cur;
}
}
cur = cur->next;
}
printf("p1::%p\n", p1);
printf("p2::%p\n", p2);
printf("p3::%p\n", p3);
printf("p4::%p\n", p4);
printf("p5::%p\n", p5);
printf("p1->data::%d\n", p1->data);
printf("p2 data::%d\n", p2->data);
printf("p3->data::%d\n", p3->data);
printf("p4->data::%d\n", p4->data);
printf("p5->data::%d\n", p5->data);
return 0;
}
输出:
p1::0x8728008
p2::0x8728018
p3::0x8728028
p4::0x8728038
p5::0x8728048
head::0x8728008
no of nodes 5
temp::0x8728008
cur::0x8728008
no of nodes 1
p1::0x8728008
p2::0x8728018
p3::0x8728028
p4::0x8728038
p5::0x8728048
p1->data::1
p2 data::2
p3->data::3
p4->data::2
p5->data::0
通过查看输出(没有节点:1)我知道节点已被删除但是不是很清楚,我甚至不知道哪个节点被删除了,p2
到p4
仍在给出相同的旧数据值,我怎么知道?
答案 0 :(得分:1)
你最后在做什么,释放整个链表?这不是你应该实现它的方式。实际上没有办法看看堆中的块是否被分配(实际上是,但编译器依赖和脏)。不要以这种方式维护链表。
free
只是将内存放回堆中,它不会改变指针的值。作为一名C程序员,你应该对动态分配的内存是否被释放表示支持,因为没有标准的方法来帮助你。
如果你只想删除列表中的第一个链接,你应该这样做:
head = cur.next;
free(cur);
然后忘掉cur
,你永远不应该使用它。
如果您想删除cur
之后的链接,则大致如下:
dll *tmp = cur->next;
cur->next = tmp->next;
free(tmp);
然后永远不会引用tmp
。
答案 1 :(得分:1)
您正在删除错误的节点,在for循环内部,fwd
变量包含重复节点,cur
变量包含原始节点< / strong>(重复)。您正在擦除原始节点和重复节点之间的节点。要仅删除重复节点,您需要在此之前维护节点并设置last_fwd->next = fwd->next;
,这将仅擦除重复节点(例如:p4 and p5
,而不是{{1}如果你需要删除它也是更多的工作)。
另一个问题是您使用指针打印节点而不是创建的p1 or p2
。在这种情况下,当你擦除linked list
和p4
并尝试打印它们的值是未定义的行为(任何事情都可能发生,工作,打印垃圾,重启机器:D等......)。
使用更新代码,使用列表的链接进行打印。在这种情况下,擦除的节点不会触摸。
代码:
p5