为何原始Linked List传入reverse函数后会丢失?
链表反转后原链表丢失的原因分析
你这段代码的核心问题在于:reverse函数是原地反转链表,直接修改了原链表的节点指针结构,导致原链表被彻底破坏。
具体原因拆解
- 当你在
isPalindrome里执行Node *temp = head;时,temp和head指向的是同一个链表的头节点——并没有复制出一个新链表,只是多了一个指向原链表的指针。 - 调用
reverse(temp)时,函数内部会遍历链表,把每个节点的next指针反向:原链表头节点的next会被改成NULL,第二个节点的next指向头节点,以此类推。这直接修改了原链表的所有节点指针,原链表的结构完全被打乱:原本的头节点变成了反转后链表的尾节点,原链表后续的节点都被挂到反转后的链表上,原链表自然就只剩下一个孤立的头节点,看起来像是“丢失”了。 - 之后你再用
temp = head;遍历原链表时,只能访问到头节点,后面的节点都已经不属于原链表了。
解决办法
要判断回文链表,不能直接反转原链表,得反转原链表的副本,或者用更高效的快慢指针法(反转后半部分链表):
方法1:复制链表后反转副本
先复制原链表得到一个新链表,再反转这个新链表,这样原链表结构不会被破坏:
// 辅助函数:复制链表 Node* copyList(Node* head) { if (head == NULL) return NULL; Node* newHead = new Node(head->data); Node* curr = newHead; Node* originalCurr = head->next; while (originalCurr != NULL) { curr->next = new Node(originalCurr->data); curr = curr->next; originalCurr = originalCurr->next; } return newHead; } Node *reverse(Node *head) { Node *prevNode = NULL, *currNode = head; while (currNode != NULL) { Node *nextNode = currNode->next; currNode->next = prevNode; prevNode = currNode; currNode = nextNode; } return prevNode; } bool isPalindrome(Node *head) { Node *copiedList = copyList(head); Node *reversedList = reverse(copiedList); Node *temp = head; while (temp != NULL) { if (temp->data != reversedList->data) { return false; } temp = temp->next; reversedList = reversedList->next; } return true; }
方法2:快慢指针+反转后半部分(更高效)
用快慢指针找到链表中间节点,反转后半部分链表,再和前半部分比较,完成后还可以把后半部分反转回来恢复原链表:
Node *reverse(Node *head) { Node *prevNode = NULL, *currNode = head; while (currNode != NULL) { Node *nextNode = currNode->next; currNode->next = prevNode; prevNode = currNode; currNode = nextNode; } return prevNode; } bool isPalindrome(Node *head) { if (head == NULL || head->next == NULL) return true; // 快慢指针找中间节点 Node *slow = head, *fast = head; while (fast->next != NULL && fast->next->next != NULL) { slow = slow->next; fast = fast->next->next; } // 反转后半部分链表 Node *reversedHalf = reverse(slow->next); Node *p1 = head, *p2 = reversedHalf; bool isPalin = true; // 比较前半和反转后的后半 while (p2 != NULL) { if (p1->data != p2->data) { isPalin = false; break; } p1 = p1->next; p2 = p2->next; } // 恢复原链表(可选,根据需求) slow->next = reverse(reversedHalf); return isPalin; }
内容的提问来源于stack exchange,提问作者Bharat Sharma
相关产品推荐
相关产品推荐

