【问题标题】:Deleting select nodes from linked list从链表中删除选择节点
【发布时间】:2015-08-10 10:20:01
【问题描述】:

我浏览了一些解释双向链表中节点删除的文章,但我无法理解为什么以下代码不起作用。请提出一些解决方案。

我有两个结构 A 和 B。有一个结构 A 的链表,每个结构都包含 B 的双向链表。我试图从每个 A 中删除所有 Id 小于值的 B 结构.这是我正在尝试的方法。

typedef struct __B {
    int id;
    struct __B *next;
    struct __B *prev;
} B;

typedef struct __A {
    B *bList;
    struct __A *next;
} A;

void DeleteNodes(int value, A* AList) {
    while(AList != NULL) {
        B *BList = AList->bList;
        while(BList != NULL) {
            B *temp = BList;
            BList = BList->next;
            if(temp->id < value) {
                if(temp->prev == NULL) // delete first node
                    BList->prev = NULL;
                else {
                    temp->prev->next = BList;
                    temp->next->prev = temp->prev;
                }
                temp->next = NULL;
                temp->prev = NULL;
                free(temp);
                temp = NULL;
            }
        }
        AList = AList->next;
    }
}

但是当我遍历 AList 和相应的 BLists 时,明显删除的节点仍然存在,这导致应用程序崩溃。 请分享一些建议。

【问题讨论】:

  • OT:根据 C11Draft/7.1.3,__B 的定义是不允许的:“所有以下划线开头的标识符,无论是大写字母还是另一个下划线,始终保留给任何用途。" (iso-9899.info/n1570.html#7.1.3)

标签: c pointers linked-list free


【解决方案1】:

您没有在 while 循环中更新 AList-&gt;bList,这就是它一直指向已删除项目的原因。 更改您的代码以更新AList-&gt;blist

void DeleteNodes(int value, A* AList) {
    while(AList != NULL) {
        B *BList = AList->bList;
        while(BList != NULL) {
            B *temp = BList;
            BList = BList->next;
            if(temp->id < value) {
                if(temp->prev == NULL) // delete first node
                    BList->prev = NULL;
                else {
                    temp->prev->next = BList;
                    temp->next->prev = temp->prev;
                }
                temp->next = NULL;
                temp->prev = NULL;
                free(temp);
                temp = NULL;
            }
        }
        AList->bList = BList;
        AList = AList->next;
    }
}

【讨论】:

  • 没有更新的是AList-&gt;bList,而不是AList本身。您的代码是正确的,但描述是错误的。
  • 我认为这会使AList-&gt;bList NULL 因为BList 被循环直到它为NULL
  • @Nishant 实际上 BaluRaman 是对的;仅当列表的第一个节点被删除时才应设置AList-&gt;bList = BList(与BList-&gt;prev = NULL 相同的位置)。
【解决方案2】:

您忘记将 AList->bList 设置为列表的新头部。

当你 free() temp 指向的内容时,你还需要确保指针 AList->bList 指向列表中的下一项。由于您不更新它,它一直指向现在 free()d BList 项并呈现未指定的结果。

AList = AList-&gt;next;之前将AList-&gt;bList设置为BList

【讨论】:

    猜你喜欢
    • 2013-01-08
    • 2017-10-21
    • 2013-08-30
    • 2020-02-04
    • 2019-05-10
    相关资源
    最近更新 更多