В односвязном списке функция дублирования не работает для последнего элемента
Нужно дублировать элементы списка поле дата которых есть чётное число (дубликат вставить перед нужным элементом)Мне казалось что функция(copy) рабочая , но когда я изменил число элементов в списке я заметил что последний элемент списка не дублируется в том случае если количество элементов не четное , не понимаю почему это происходит
Изначально список состоит из 3 элементов :(2,3,4) после функции copy выходит :(2,2,3,4) а должно:(2,2,3,4,4)
Изменил функцию copy : добавил еще один указатель для анализа работы по tmp а не по tmp->next , но почему-то не работает ,думаю, что это может быть из-за того , что я не правильно использовал указатель back .
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>
struct TNode {
int data;
struct TNode *next;
};
typedef struct TNode Node;
void CreateNode(Node** head, int d)
{
Node *tmp = (Node*)malloc(sizeof(Node));
tmp->data = d;
tmp->next = (*head);
(*head) = tmp;
}
void copy(Node** head)
{
Node *tmp;
Node *back;
tmp = (*head);
back = (*head);
while (tmp != NULL)
{
if (tmp = (*head) && tmp->data % 2 == 0)
{
Node *P1 = (Node*)malloc(sizeof(Node));
P1->data = (*head)->data;
P1->next = (*head);
(*head) = P1;
}
else if (tmp->data % 2 == 0)
{
Node *P1 = (Node*)malloc(sizeof(Node));
back->next = tmp;
P1->data = back->next->data;
P1->next = back->next;
back->next = P1;
}
tmp = tmp->next;
}
}
int main()
{
setlocale(LC_ALL, "ukr");
Node *head = NULL;
for (int i = 0; i < 3; i++)
{
CreateNode(&head, i + 2);
}
Node *tmp = head;
/*copy(&head);
while (tmp)
{
printf("%d\n", tmp->data);
tmp = tmp->next;
}
copy(&head);
Node *i = head;
while (i)
{
printf(" %d\n", i->data);
i = i->next;
}
getchar();
return 1;
}
Ответы (2 шт):
if (tmp = (*head) && tmp->data % 2 == 0)У вас опечатка, нужно использовать не знак присваивания, а сравнения==.backэто же предыдущий элемент относительноtmp, тогда его нужно обновлять также, как иtmp.back = tmpОбязательно перед
tmp = tmp->next
И немного можно украсить код)
Во 2-ом
ifможно написать так:Node* P1 = (Node*)malloc(sizeof(Node)); P1->data = tmp->data; P1->next = tmp; back->next = P1;Я думаю тут понятно, что
back->next = tmpбыла лишней и можно обращаться кtmp.Можно заметить, что есть похожие строчки кода, по этому избавимся от них
if (tmp->data % 2 == 0) { Node* P1 = (Node*)malloc(sizeof(Node)); P1->data = tmp->data; P1->next = tmp; if (tmp == (*head)) (*head) = P1; else back->next = P1; }
Если вставлять дубликат не до, а после элемента с четными данными, то программа будет более элегантна
(кстати, в этом случае в функцию копирования можно передавать не указатель на голову списка, а сам голову (указатель на элемент списка)).
void copy(Node* head)
{
for (Node *tmp = head; tmp; tmp = tmp->next)
if (tmp->data % 2 == 0) {
Node *p = (Node*)malloc(sizeof(Node));
*p = *tmp; // да, структуры можно копировать, теперь p->next = tmp->next
tmp->next = p;
tmp = p; // это для правильного перехода к следующему элементу
}
}