gpt4 book ai didi

c - 使用链表理解类型函数

转载 作者:太空宇宙 更新时间:2023-11-04 03:14:04 24 4
gpt4 key购买 nike

大家早上好/晚上好,我想在脑海中澄清以下关于链表函数的概念(在本例中是递归的)。

让我们采用以下程序递归地消除链表中的重复项:

ElementoDiLista* deleteDuplicates(ElementoDiLista* head)
{
if (head == NULL)
{
return NULL;
}
if (head->next == NULL)
{
return head;
}
if (head->info == head->next->info)
{
ElementoDiLista *tmp;
tmp = head->next;
head->next = head->next->next;
free(tmp);
return deleteDuplicates(head);
}
else
{
head->next = deleteDuplicates(head->next);
return head;
}
}

使用我的结构定义并以这种方式列出:

struct el {int info; struct el *next;};
typedef struct el ElementoDiLista;
typedef ElementoDiLista *ListaDiElementi;

然后在主体中我这样调用函数:

Lista1 = deleteDuplicates(Lista1);

Lista1 声明如下:ElementoDiLista Lista1 = NULL

我的问题是,我被用来声明无效的或依赖于单一类型的函数(int、float ecc...)我想澄清两件事:

  1. 为什么函数声明为 ElementoDiLista* deleteDuplicates(ElementoDiLista* head) 因为对我来说这样更直观 ListaDiElementi deleteDuplicates (ListaDiElementi *head)但不幸的是,这是行不通的。

  2. 我不是很清楚函数返回 head 或 NULL 值的原因,但这就是我认为为什么在主 Lista1 中采用函数值的原因,因为函数修改了列表本身,我我对吗?

如果问题不是很令人兴奋,我很抱歉,我只是非常努力地总体上理解列表并且非常困难,任何帮助或建议将不胜感激,

谢谢大家!

最佳答案

Why the function is declared as ElementoDiLista* deleteDuplicates(ElementoDiLista* head) because to me it is more intuitive this way ListaDiElementi deleteDuplicates (ListaDiElementi *head)

从参数开始,最初声明为,

ElementoDiLista* head

所以它需要一个指向头元素的指针。这将等同于(更改变量名称)

ListaDiElementi list 

所以我们传递一个“列表”作为参数,它是一个指向头部的指针。该指针未被修改。确实要修改它,我们需要按照您的建议使用,

ElementoDiLista** head

或者等价地,也许更具可读性,

ListaDiElementi* list 

因此问题是,“我们是否需要修改指向头部的指针”?或者换句话说,是否需要修改原始列表指针?答案是

如果列表为空,它将保持为空。如果列表不为空,则头部将保持不变。您不会移除头部,只有跟随的节点具有与头部相同的值。

It is not very clear to me why the function returns head or NULL values, but this is the reason i think why in the main Lista1 takes the value of the function, because the function modifies the list itself, am i right ?

我个人不喜欢函数返回指向元素(即列表)的指针。此外,它似乎总是返回 head,并且以一种相当困惑的方式实现。

首先关于我不喜欢它。如果您正在更改现有列表的结构,而不是创建一个新列表,您希望您的初始指针在该过程之后保持有效。所以你改变那个指针(如果你需要的话)而不是返回一个新的。在这种情况下,它甚至不会改变。所以我要么让它 void 要么返回一些退出代码。

其次看代码,

if (head == NULL)
{
return NULL;

它返回了 head 因为它是空的。

if (head->next == NULL)
{
return head;

它又回头了。

if (head->info == head->next->info)
{
ElementoDiLista *tmp;
tmp = head->next;
head->next = head->next->next;
free(tmp);
return deleteDuplicates(head);
}

它返回 deleteDuplicates(head) 并且 head 是未更改的原始参数。因此,如果所有其他情况都返回 head,那么这个也会。

else
{
head->next = deleteDuplicates(head->next);
return head;
}

这也返回 head(注意 head 没有改变)。所以它的返回值总是原始参数head。所以这是没有意义的。

此外请注意,在前两种情况下您什么都不做,您只是返回一个无用的值。

if (head == NULL)
{
return NULL;
}
if (head->next == NULL)
{
return head;
}

因此,如果您确实将过程更改为void,此代码就会消失。如果您的列表或其尾部为空,则您无需执行任何操作,因为没有重复项。

关于c - 使用链表理解类型函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53579744/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com