c-用链表理解类型函数



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

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

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中取函数的值的原因,因为函数修改了列表本身,我是对的吗?

如果问题不是很令人兴奋,我很抱歉,我只是很难理解列表的总体内容,而且非常困难,任何帮助或建议都将不胜感激,

无论如何,谢谢大家!

为什么函数被声明为ElementoDiLista* deleteDuplicates(ElementoDiLista* head),因为对我来说,这样ListaDiElementi deleteDuplicates (ListaDiElementi *head)更直观

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

ElementoDiLista* head

所以它取一个指向head元素的指针。这相当于(变量名称更改后(

ListaDiElementi list 

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

ElementoDiLista** head

或者等效地并且可能更可读的

ListaDiElementi* list 

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

如果列表为空,则它将保持为空。如果列表不为空,则标题将保持不变。不会移除头,只移除后面的节点,这些节点的值与头的值相同。

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

就我个人而言,我不喜欢函数返回指向元素(即列表(的指针。此外,它似乎总是返回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是未更改的原始参数。所以,如果所有其他情况都返回头部,那么这也会返回头部。

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

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

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

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

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

相关内容

  • 没有找到相关文章

最新更新