Почему функция объявлена как ElementoDiLista* deleteDuplicates(ElementoDiLista* head)
, потому что для меня это более интуитивно понятно ListaDiElementi deleteDuplicates (ListaDiElementi *head)
Начиная с аргумента, первоначально она объявляется как,
ElementoDiLista* head
, поэтому требуется указатель на элемент head.Это было бы эквивалентно (с изменением имени переменной):
ListaDiElementi 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
, этот код исчезнет.Вам не нужно ничего делать, если ваш список или его хвост нулевой, так как дубликатов нет.