0

我有一个结构:

struct Node {
    int value;
    struct Node *next;
};

typedef struct Node List;

而且我已经实现了将项目添加到列表中,但是当它是给定列表中的第一个元素时,我从列表中删除元素时遇到问题,我的函数:

void removeItem(List *ptr, int i)
{
    List *current = ptr;
    List *prev = NULL;
while (current != NULL)
{
    if (current->value == i)
    {
                    //it's first element
        if (prev == NULL)
        {
            List *replace = ptr->next;
            free(current);
            ptr = replace;
            current = replace;
        }
        else
        {
            prev->next = current->next;
            free(current);
            current = prev->next;
        }
    }
    else
    {
        prev = current;
        current = current->next;
    }
}
}

当我的清单是这样的:

1、2、3、4、5

使用removeItem(list, 1)后,它是:

0、2、3、4、5

0不应该在那里。

另一个问题是,当 typedef 不同时,我也应该实现这些功能:

typedef struct Node *List;

但是后来我得到了大量的“错误的参数类型”/“在不是结构或联合的东西中请求成员'值'”错误。我能找到一些应该如何处理的例子吗?

4

3 回答 3

2

您的问题是您传入 ( list) 的变量不会被您的删除代码修改。因此,当NodeList删除.NodeList

原因是这样的:

当您调用 时removeItem(list, 1),您传递的是 的值list。在这种情况下,它是类型为 的数据地址List。在removeItem函数内部,该值由ptr变量携带。当您输入函数时,ptr变量是您的地址,您List可以使用它进行工作。在该行ptr = replace中,您所做的只是更改ptr. 它不影响被调用list范围内的值。removeItem

最简单的做法是removeList返回一个指向结果列表头部的指针。对于大多数呼叫,它将与来电相同ptr;只有当removedNode位于 的头部时List,结果指针才会不同。

或者,您可以进行更改removeList,使其需要一个指向 a 的指针List,然后将其称为 as removeList(&list, 1),这将允许您直接修改 in 的值list

于 2013-01-18T19:02:19.210 回答
1

这看起来像一个家庭作业问题,所以我不想直接回答,但有两个线索:

  • 如果您的目标是更改函数调用中列表指向的removeItem()内容,那么第一个参数的类型removeItem()需要是什么?

  • 如果我告诉您,在某些实现中,free()将指针变量清零以帮助调试该变量指向的空间,这会帮助您理解所获得的输出吗?

当你得到这个工作时,请随时发布你自己问题的答案。

于 2013-01-18T19:02:56.000 回答
0

所有答案都有帮助,这是最终功能:

void removeItem(List *ptr, int i)
{
    while ((*ptr) != NULL)
    {
        if ((*ptr)->value == i)
        {
            List tmp = *ptr;
            *ptr = (*ptr)->next;
            free(tmp);
        }
        else
        {
            ptr = &((*ptr)->next);
        }
    }
}

正常工作:

List ptr = malloc(sizeof(List));

//add items to list:
//1, 1, 2, 3, 4, 4, 5, 5,

removeItem(&ptr, 5);
removeItem(&ptr, 2);
removeItem(&ptr, 1);

//print and clean
//3, 4, 4, 
于 2013-01-20T16:33:24.657 回答