使用链表理解类型函数
Understanding type functions with linked-list
大家好Morning/Evening
我想在脑海中澄清以下关于链表函数的概念(在本例中是递归的)。
让我们看下面这个递归消除链表中重复项的程序:
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...)
我想澄清两件事:
为什么函数声明为 ElementoDiLista* deleteDuplicates(ElementoDiLista* head)
因为对我来说这样更直观 ListaDiElementi deleteDuplicates (ListaDiElementi *head)
但不幸的是,它不起作用。
我不是很清楚为什么函数 returns 头或 NULL 值,但这就是我认为为什么在 main 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
所以我们将作为参数传递 "list",它是指向头部的指针。该指针未被修改。要修改它,我们确实需要按照您的建议使用,
ElementoDiLista** head
或等价地,也许更具可读性,
ListaDiElementi* list
那么问题来了,"do we need to modify the pointer to the head"? 或者说,原来的链表指针需要修改吗?答案是否。
如果列表为空,它将保持为空。如果列表不为空,则头部将保持不变。您不会移除头部,只有跟随的节点具有与头部相同的值。
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 ?
我个人不喜欢函数 return 是指向元素(即列表)的指针。此外,它似乎总是 return head
,并且以一种相当混乱的方式实现。
首先关于我不喜欢它。如果您正在更改现有列表的结构,而不是创建一个新列表,您希望您的初始指针在该过程之后保持有效。所以你改变那个指针(如果你需要的话)而不是 returning 一个新的。在这种情况下,它甚至不会改变。所以我要么让它 void
要么 return 一些退出代码。
其次看代码,
if (head == NULL)
{
return NULL;
它 returned head
因为它是空的。
if (head->next == NULL)
{
return head;
它又 return 头了。
if (head->info == head->next->info)
{
ElementoDiLista *tmp;
tmp = head->next;
head->next = head->next->next;
free(tmp);
return deleteDuplicates(head);
}
它returns deleteDuplicates(head)
和head
是没有改变的原始参数。因此,如果所有其他情况 return 领先,那么这也是如此。
else
{
head->next = deleteDuplicates(head->next);
return head;
}
这也是 returns head
(注意 head
没有改变)。所以它的 return 值总是原始参数 head
。所以这是没有意义的。
此外请注意,在前两种情况下您什么都不做,您只是 return 一个无用的值。
if (head == NULL)
{
return NULL;
}
if (head->next == NULL)
{
return head;
}
因此,如果您将程序更改为 void
,此代码就会消失。如果您的列表或其尾部为空,则您无需执行任何操作,因为没有重复项。
大家好Morning/Evening 我想在脑海中澄清以下关于链表函数的概念(在本例中是递归的)。
让我们看下面这个递归消除链表中重复项的程序:
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...) 我想澄清两件事:
为什么函数声明为
ElementoDiLista* deleteDuplicates(ElementoDiLista* head)
因为对我来说这样更直观ListaDiElementi deleteDuplicates (ListaDiElementi *head)
但不幸的是,它不起作用。我不是很清楚为什么函数 returns 头或 NULL 值,但这就是我认为为什么在 main Lista1 中取函数值的原因,因为该函数修改列表本身,对吗?
如果问题不是很令人兴奋,我很抱歉,我只是非常努力地总体上理解列表并且非常困难, 如有任何帮助或建议,我们将不胜感激,
谢谢大家!
Why the function is declared as
ElementoDiLista* deleteDuplicates(ElementoDiLista* head)
because to me it is more intuitive this wayListaDiElementi deleteDuplicates (ListaDiElementi *head)
从参数开始,最初声明为,
ElementoDiLista* head
所以它需要一个指向头元素的指针。这将等同于(更改变量名称)
ListaDiElementi list
所以我们将作为参数传递 "list",它是指向头部的指针。该指针未被修改。要修改它,我们确实需要按照您的建议使用,
ElementoDiLista** head
或等价地,也许更具可读性,
ListaDiElementi* list
那么问题来了,"do we need to modify the pointer to the head"? 或者说,原来的链表指针需要修改吗?答案是否。
如果列表为空,它将保持为空。如果列表不为空,则头部将保持不变。您不会移除头部,只有跟随的节点具有与头部相同的值。
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 ?
我个人不喜欢函数 return 是指向元素(即列表)的指针。此外,它似乎总是 return head
,并且以一种相当混乱的方式实现。
首先关于我不喜欢它。如果您正在更改现有列表的结构,而不是创建一个新列表,您希望您的初始指针在该过程之后保持有效。所以你改变那个指针(如果你需要的话)而不是 returning 一个新的。在这种情况下,它甚至不会改变。所以我要么让它 void
要么 return 一些退出代码。
其次看代码,
if (head == NULL) { return NULL;
它 returned head
因为它是空的。
if (head->next == NULL) { return head;
它又 return 头了。
if (head->info == head->next->info) { ElementoDiLista *tmp; tmp = head->next; head->next = head->next->next; free(tmp); return deleteDuplicates(head); }
它returns deleteDuplicates(head)
和head
是没有改变的原始参数。因此,如果所有其他情况 return 领先,那么这也是如此。
else { head->next = deleteDuplicates(head->next); return head; }
这也是 returns head
(注意 head
没有改变)。所以它的 return 值总是原始参数 head
。所以这是没有意义的。
此外请注意,在前两种情况下您什么都不做,您只是 return 一个无用的值。
if (head == NULL) { return NULL; } if (head->next == NULL) { return head; }
因此,如果您将程序更改为 void
,此代码就会消失。如果您的列表或其尾部为空,则您无需执行任何操作,因为没有重复项。