C:函数do删除通用链表上的节点

C:函数do删除通用链表上的节点,c,algorithm,data-structures,linked-list,C,Algorithm,Data Structures,Linked List,我在编写一个函数来删除通用链表上的节点时遇到问题 我的链接列表声明如下(这是我的教授希望我们这样做的方式): 我使用这个函数来删除永久==FALSE的所有节点,但它实际上不起作用 void DeleteFuncNotPermanent(LIST *list) { LIST *node = list; while ((*list)->next != NULL) { if(((FUNC*)DATA(*list))->permament == F

我在编写一个函数来删除通用链表上的节点时遇到问题

我的链接列表声明如下(这是我的教授希望我们这样做的方式):

我使用这个函数来删除永久==FALSE的所有节点,但它实际上不起作用

void DeleteFuncNotPermanent(LIST *list)
{

    LIST *node = list;

    while ((*list)->next != NULL)
    {
        if(((FUNC*)DATA(*list))->permament == FALSE)
        {
            node = list;
            list = &(NEXT(*node));

            free(DATA(*node));
            free(*node);

        }
        else
        {
            list = NEXT(*list);
        }
    }
}

如有任何反馈,将不胜感激。多谢各位

使用指向节点指针的指针遍历列表,这是一个好主意。(然而,打字摆脱
列表的指针性质并不是一个好主意。)yur代码中有几个错误

要获取指向列表最后一个元素的指针,请执行以下操作:

Node **p = &head;

while (*p) {
    p = &(*p)->next;
}
您各自的代码,即没有删除内容的函数,如下所示:

    while ((*list)->next != NULL) {
        list = NEXT(*list);
    }
您应该在(*list)
时迭代
。检查
next
的想法可能源于使用节点指针进行迭代的类似代码。使用指向节点指针的指针时,取消引用该指针与访问
next
具有相同的效果,因为该指针首先指向头节点,然后在后续迭代中指向前一个节点的
next
成员

这就是为什么当您要推进指针时,必须将
(*list)->next
的地址分配给
list
。(comiler警告您指针类型不匹配。)

因此,“原始”循环应该是:

    while (*list != NULL) {
        list = &NEXT(*list);
    }
现在让我们看一下删除。确定应删除节点后,您可以执行以下操作:

    LIST *node = list;

    list = &(NEXT(*node));

    free(DATA(*node));
    free(*node);
在这里,您不想推进迭代器指针。相反,您希望更新它所指向的内容:您希望通过将指向该节点的指针偏转到下一个节点或指向
NULL
(当该节点是最后一个节点时)来跳过当前节点
*列表

    *list = NEXT(*node);
执行此操作时,
列表
节点
仍将是相同的地址,只是内容已更改。(因为
node==list
*node
现在指向要删除的节点后的节点,并且意外地释放了该节点及其数据。将临时指针设为简单的节点指针:

    LIST node = *list;

    *list = NEXT(node);

    free(DATA(node));
    free(node);
总而言之:

void DeleteFuncNotPermanent(LIST *list, int c)
{
    while (*list)
    {
        if (((FUNC*) DATA(*list))->permament == FALSE)
        {
            LIST node = *list;

            *list = (NEXT(*list));

            free(DATA(node));
            free(node);
        }
        else
        {
            list = &NEXT(*list);
        }
    }
}

您可以使用指向节点指针的指针来遍历列表,这是一个好主意。(但是,键入去掉
list
的指针性质并不是一个好主意。)yur代码中有几个错误

要获取指向列表最后一个元素的指针,请执行以下操作:

Node **p = &head;

while (*p) {
    p = &(*p)->next;
}
您各自的代码,即没有删除内容的函数,如下所示:

    while ((*list)->next != NULL) {
        list = NEXT(*list);
    }
您应该在(*list)时迭代
。检查
next
的想法可能源于使用节点指针进行迭代的类似代码。当使用指向节点指针的指针时,取消引用该指针与访问
next
具有相同的效果,因为该指针首先指向头节点,然后指向子节点上的前一个节点的
next
成员重复迭代

这就是为什么当您要推进指针时,必须将
(*list)->next
的地址分配给
list
。(comiler警告您指针类型不匹配。)

因此,“原始”循环应该是:

    while (*list != NULL) {
        list = &NEXT(*list);
    }
现在让我们看一下删除。当您确定应该删除节点时,您将执行以下操作:

    LIST *node = list;

    list = &(NEXT(*node));

    free(DATA(*node));
    free(*node);
在这里,您不希望推进迭代器指针。相反,您希望更新它指向的内容:您希望通过将指向该节点的指针偏转到下一个节点或指向上一个节点时的
NULL
,跳过当前节点
*列表

    *list = NEXT(*node);
执行此操作时,
list
node
仍将是相同的地址,只是内容已更改。(因为
node==list
*node
现在指向要删除的节点后的节点,并且意外地释放了该节点及其数据。将临时指针设为简单的节点指针:

    LIST node = *list;

    *list = NEXT(node);

    free(DATA(node));
    free(node);
总而言之:

void DeleteFuncNotPermanent(LIST *list, int c)
{
    while (*list)
    {
        if (((FUNC*) DATA(*list))->permament == FALSE)
        {
            LIST node = *list;

            *list = (NEXT(*list));

            free(DATA(node));
            free(node);
        }
        else
        {
            list = &NEXT(*list);
        }
    }
}

我试图重写你的删除函数。请告诉我它是否有效。这些更改基本上与指针取消引用有关

void DeleteFuncNotPermanent(LIST *list)
{

    LIST *node = list;

    while (list!= NULL)    // change
    {
        if(((FUNC*)(DATA(list)))->permament == FALSE)   // change
        {
            node = list;
            list = NEXT(node);  //change

            free((FUNC*)(DATA(node)));  // change
            free(node);       // change

        }
        else
        {
            list = NEXT(list);    //change
        }
    }
}



我试图重写你的删除函数。请告诉我它是否有效。这些更改基本上与指针取消引用有关

void DeleteFuncNotPermanent(LIST *list)
{

    LIST *node = list;

    while (list!= NULL)    // change
    {
        if(((FUNC*)(DATA(list)))->permament == FALSE)   // change
        {
            node = list;
            list = NEXT(node);  //change

            free((FUNC*)(DATA(node)));  // change
            free(node);       // change

        }
        else
        {
            list = NEXT(list);    //change
        }
    }
}



在一个分配给列表的任务中,你将指针分配给一个指针,而在另一个任务中,你将指针分配给一个指针。其中一个是错误的。我想所有的宏和非直观的typedef都应该让一切变得更清楚,但它们确实让一切变得更复杂。另外,如果你能比“但它真的不起作用”更具体一点,那就好了。关于:
\u STATUS
\u BOOLEAN
前导下划线后跟大写字母是为语言实现“保留”的。在一个分配列表中,您将指针分配给指针,在另一个分配列表中,您将指针分配给指针。其中一个是错误的。我猜所有宏和非直观的typedef都应该使所有内容都是c学习者,但他们真的让一切变得更复杂。而且,如果你能比“但它真的不起作用”更具体一点,那就好了。关于:
\u STATUS
\u BOOLEAN
为语言实现保留了一个前导下划线,后跟一个大写字母。我真的想感谢你花了这么多时间来编写这个全面的答案。这不仅对我有帮助,对其他问题也有帮助。我相信这会有所帮助也有更多的人。谢谢。我真的想感谢你花了这么多时间来写这个全面的答案。这不仅在这个具体问题上对我有帮助,在其他问题上也有帮助。我相信这也会帮助更多的人。谢谢。