首页 > 解决方案 > C:函数do删除通用链表上的节点

问题描述

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

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

typedef enum _STATUS {ERROR,OK} STATUS;
typedef enum _BOOLEAN {FALSE, TRUE} BOOLEAN;

#define MAX_NOME 20


typedef struct _FUNC
{
    char name[MAX_NOME];
    char dept[MAX_NOME];
    BOOLEAN permanent;
} FUNC;


typedef struct _LIST_NODE
{
    void * data;
    struct _LIST_NODE * next;
} LIST_NODE;


typedef LIST_NODE * LIST;

#define DATA(node) ((node)->data)
#define NEXT(node) ((node)->next)

我提供了这个功能来删除所有具有永久 == 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);
        }
    }
}

任何反馈将不胜感激。谢谢你。

标签: calgorithmdata-structureslinked-list

解决方案


您使用指向节点指针的指针遍历列表,这是一个好主意。(但是,类型转换掉指针性质LIST并不是一个好主意。)您的代码中有几个错误。

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

Node **p = &head;

while (*p) {
    p = &(*p)->next;
}

您各自的代码,即没有删除内容的函数,如下所示:

    while ((*list)->next != NULL) {
        list = NEXT(*list);
    }

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

这就是为什么当您想要推进指针时必须分配(*list)->nextto的地址。list(编译器警告您指针类型不匹配。)

所以“原始”循环应该是:

    while (*list != NULL) {
        list = &NEXT(*list);
    }

现在让我们看看删除。当您确定应该删除该节点时,您可以执行以下操作:

    LIST *node = list;

    list = &(NEXT(*node));

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

在这里,您不想推进迭代器指针。相反,您想更新它指向的内容:您想*list通过将指向该节点的指针偏转到下一个节点或指向 的指针来跳过当前节点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);
        }
    }
}

推荐阅读