如何在链表中检查节点是否被删除

时间:2014-09-04 17:21:24

标签: c singly-linked-list

嘿,请有人清楚我的疑问,如果我删除一个节点,后来我尝试打印该节点的数据应该是什么输出?如何检查节点是否被删除?

在这个程序中,我试图删除重复的节点以及如何知道我是否正确删除它们!我想删除一个节点后,如果我尝试访问该删除的节点的数据,如果一切正常,我将得到零!但这就是这种情况,所以我再次尝试计算节点,这很好。计算唯一的检查方法吗?

#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)我知道节点已被删除但是不是很清楚,我甚至不知道哪个节点被删除了,p2p4仍在给出相同的旧数据值,我怎么知道?

2 个答案:

答案 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 listp4并尝试打印它们的值是未定义的行为(任何事情都可能发生,工作,打印垃圾,重启机器:D等......)。

使用更新代码,使用列表的链接进行打印。在这种情况下,擦除的节点不会触摸。

代码:

p5