在这里使用函数returnReverseLinkedList
我返回给定链表的反向链表。但是这种方法的问题在于我丢失了原始链表。因此,我做了另一个叫做createReversedLinkedList
的功能,以copy of the original linked list
,reverse the copy
并保持对两者的占有。 不幸的是,createReversedLinkedList
给了Runtime error
. 显然,我的最终目标是检查if the given linked list is palindrome or not
.这个问题只是一个垫脚石。 有人能告诉我为什么吗?
//Check if a linked list is a palindrome
#include <iostream>
using namespace std;
class node
{
public:
int data;
node *next;
node(int data)
{
this->data = data;
this->next = NULL;
}
};
node *returnReverseLinkedList(node *head)
{
// Will Lose original Linked List
if (head == NULL)
return NULL;
else if (head != NULL && head->next == NULL)
return head;
node *prev = NULL;
node *curr = head;
node *tempNext = head->next;
while (tempNext != NULL)
{
curr->next = prev;
prev = curr;
curr = tempNext;
tempNext = tempNext->next;
}
curr->next = prev;
return curr;
}
node *createReversedLinkedList(node *head)
{
if (head == NULL)
return NULL;
else if (head != NULL && head->next == NULL)
return NULL;
else
{
node *temp = head;
node *newHead = NULL;
node *newTail = NULL;
while (temp != NULL)
{
node *newNode = new node(temp->data);
if (newHead == NULL)
{
newHead = newNode;
newTail = newNode;
}
else
{
newTail->next = newNode;
newTail = newNode;
}
}
return returnReverseLinkedList(newHead);
}
}
bool check_palindrome(node *head)
{
node *original = head;
node *reverse = returnReverseLinkedList(head);
while (original->next != NULL || reverse->next != NULL)
{
if (original->data != reverse->data)
return false;
cout << "debug 2" << endl;
original = original->next;
reverse = reverse->next;
}
return true;
}
// #include "solution.h"
node *takeinput()
{
int data;
cin >> data;
node *head = NULL, *tail = NULL;
while (data != -1)
{
node *newnode = new node(data);
if (head == NULL)
{
head = newnode;
tail = newnode;
}
else
{
tail->next = newnode;
tail = newnode;
}
cin >> data;
}
return head;
}
void print(node *head)
{
node *temp = head;
while (temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
int main()
{
node *head = takeinput();
node *revese2 = createReversedLinkedList(head);
print(revese2);
// bool ans = check_palindrome(head);
// if (ans)
// cout << "true";
// else
// cout << "false";
// return 0;
}
正如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
函数中,您永远不会释放动态反向副本(事实上,您不能释放,因为您在第一次遍历后丢弃了引用其头部的原始指针:
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;
}