В соответствии с запросом OP, построение обратной ссылки просто выполняется путем построения, как если бы стек (например, LIFO), а не дублировал одну и ту же исходную прямую цепочку. Например:
node *createReversedLinkedList(const node *head)
{
node *newHead = NULL;
for (; head; head = head->next)
{
node *p = new node(head->data)
p->next = newHead;
newHead = p;
}
return newHead;
}
Обратите внимание, что мы не вешаем наши скопированные узлы на хвост нового списка; они висят в заголовке нового списка и становятся новыми в каждом добавлении. Вот и все. Нет необходимости составлять идентичный список, а затем изменять его; вы можете перевернуть его при создании копии для начала.
Примечание к оставшейся части кода. У вас ужасная утечка памяти, даже если вы исправите процесс обращения, как я показал выше. В вашей функции check_palindrome
вы никогда не освобождаете обратную динамическую c копию (и на самом деле вы не можете этого сделать, потому что после первого обхода вы отбрасываете оригинальный указатель, ссылающийся на его голову:
bool check_palindrome(node *head)
{
node *original = head;
node *reverse = returnReverseLinkedList(head); // only reference to reversed copy
while (original->next != NULL || reverse->next != NULL)
{
if (original->data != reverse->data)
return false; // completely leaked entire reversed copy
original = original->next;
reverse = reverse->next; // lost original list head
}
return true;
}
Наиболее очевидный метод борьбы с этой ужасной утечкой - запомнить исходный список и использовать другой указатель для итерации, и не выходить из функции до тех пор, пока копия не будет освобождена.
bool check_palindrome(const node *head)
{
bool result = true;
node *reverse = returnReverseLinkedList(head);
for (node *p = reverse; p; p = p->next, head = head->next)
{
if (p->data != head->data)
{
result = false;
break;
}
}
while (reverse)
{
node *tmp = reverse;
reverse = reverse->next;
delete tmp;
}
return result;
}