【问题标题】:unable to delete a node in double linked list无法删除双链表中的节点
【发布时间】:2014-08-22 20:15:21
【问题描述】:

我正在尝试这个没有头/开始指针,它通常会保存第一个节点的地址。我这里有 3 个节点,我试图从中删除最后一个节点,但它没有发生。我的逻辑可能有问题,这是我的第一个链表程序,所以请帮助我!

#include <stdio.h>
#include <stdlib.h>

struct dll {
    struct dll* prev;
    int data;
    struct dll* next;
};

int main() {
    struct dll* p1, *p2, *p3, *temp;
    p1 = malloc(sizeof(struct dll));
    p2 = malloc(sizeof(struct dll));
    p3 = malloc(sizeof(struct dll));
    temp = malloc(sizeof(struct dll));
    p1->prev = NULL;
    p1->data = 1;
    p1->next = p2;
    p2->prev = p1;
    p2->data = 2;
    p2->next = p3;
    p3->prev = p2;
    p3->data = 3;
    p3->next = NULL;
    struct dll* add = NULL;
    int count = 0;
    printf("add of p1::%p add of p2::%p add of p3::%p add of p1->prev::%p add "
           "of p1->next::%p add of p2->prev::%p add of p2->next::%p add of "
           "p3->prev::%p add of p3->next::%p\n",
           p1, p2, p3, p1->prev, p1->next, p2->prev, p2->next, p3->prev,
           p3->next);
    while (p1->next != NULL) {
        count++;
        p1 = p1->next;
    }
    printf("no of nodes %d\n", count + 1);
    puts("enter the addresss of node to delete it");
    scanf("%p", &add);
    while (p1->next != NULL) {
        if (p1->next == add) {
            temp = p1->next;
            p1->next = NULL;
            free(temp);
            temp = NULL;
        } else
            p1 = p1->next;
    }
    puts("after deletion attempted");
    printf("add of p1::%p add of p2::%p add of p3::%p add of p1->prev::%p add "
           "of p1->next::%p add of p2->prev::%p add of p2->next::%p add of "
           "p3->prev::%p add of p3->next::%p\n",
           p1, p2, p3, p1->prev, p1->next, p2->prev, p2->next, p3->prev,
           p3->next);

    while (p1->next != NULL) {
        count++;
        p1 = p1->next;
    }
    printf("no of nodes %d\n", count + 1);
    free(p1);
    p1 = NULL;
    free(p2);
    p2 = NULL;
    free(p3);
    p3 = NULL;
    return 0;
}

输出::::

add of p1::0x9605008 add of p2::0x9605018 add of p3::0x9605028 add of p1->prev::(nil) add of p1->next::0x9605018 add of p2->prev::0x9605008 add of p2->next::0x9605028 add of p3->prev::0x9605018 add of p3->next::(nil)

no of nodes 3

enter the addresss of node to delete it
0x9605028

after deletion attempted

add of p1::0x9605028 add of p2::0x9605018 add of p3::0x9605028 add of p1->prev::0x9605018 add of p1->next::(nil) add of p2->prev::0x9605008 add of p2->next::0x9605028 add of p3->prev::0x9605018 add of p3->next::(nil)

no of nodes 3

在此示例中,我试图通过删除其地址 0x9605028 来删除节点 3,即 p3。但是删除后节点数还是3个,地址出乎意料!

【问题讨论】:

  • 我不得不提到temp = p1-&gt;next 在第一次调用时引入了内存泄漏。指针temp 在函数顶部附近被初始化为temp=malloc(sizeof(struct dll))。它是一个指针。 C 不是 Java。实际上,您可以完全删除 main() 中的声明,并在 if{} 大括号内声明一个 local 范围指针(如果这样做可能会更清楚)。
  • 您好,感谢您的宝贵时间,但我不明白内存泄漏的部分,如果您不介意请多花点时间解释清楚为什么内存泄漏?!实际上,由于链表,我很困惑。
  • 代码应该在检查 node...next 是否为空之前检查正确的节点指针。 IE。以下需要修复:while (p1->next != NULL) { if (p1->next == add) {

标签: c doubly-linked-list


【解决方案1】:

在这个循环之后

while(p1->next!=NULL)
{
    count++;
    p1=p1->next;
}

p1->next 等于 NULL。现在 p1 指向与 p3 相同的节点。所以你有内存泄漏。

由于 p1->next 等于 NULL 那么这个循环

while(p1->next!=NULL)
{
    if(p1->next==add)
    {
        temp = p1->next;
        p1->next=NULL;
        free(temp);
        temp=NULL;
    }
    else
    p1=p1->next;
}

永远不会被迭代。

也不需要为指针 temp 分配内存

temp=malloc(sizeof(struct dll));

如果你想计算节点的数量,那么代码可以如下所示

int count = 0;

for ( temp = p1; temp != NULL; temp = temp->next ) ++count;

【讨论】:

  • 谢谢!是的,从现在开始我会好好照顾的!您的回答也正确,帮助了我,但我不能接受两个答案!别介意!
【解决方案2】:

你没有重新初始化你的变量。

在第一次“计数”之后,p1实际上是指向列表中的第三个元素,并且它永远不会放回开头(实际上,你没有存储循环开始的位置)。所以从那时起,p1-&gt;next!=NULL 是假的。其他两个循环都不运行。

请注意,您在“删除”后为p1 输出的地址与为p3 输出的地址相同。您只会得到相同的计数,因为您在尝试再次计数之前从未将 count 设置回零。

【讨论】:

  • 谢谢!是的,从现在开始我会好好照顾的!
【解决方案3】:

您将遇到的另一个问题是,当您最终删除一个节点时,您将破坏链表,除非您重置下一个和上一个 ponters。以下是有关如何执行此操作的一些逻辑。

  1. 创建一个指向要删除的节点的指针,我们称之为deleteMe
  2. 创建另一个指针以指向deletMe 的上一个或下一个节点。
  3. 然后重置您的链接。

    (deleteMe->previous)->next = deleteMe->next;

    (deleteMe->next)->previous = deleteMe->previous;

  4. 现在可以免费删除我了

  5. 但请确保您有指向第 2 步中剩余节点之一的指针,否则您将在内存泄漏中丢失列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    相关资源
    最近更新 更多