链表回文判断代码出现段错误(SIGSEGV)求调试帮助
分析你的段错误原因及修复方案
你的思路完全没问题——拆分链表、反转后半段、逐节点比较是判断链表回文的经典高效方法,但代码里有几个关键逻辑漏洞导致了段错误,咱们一步步拆解问题:
1. 最直接的段错误触发点:边界情况未处理+错误的快慢指针循环
你的while(1)循环根本没起到遍历找中间节点的作用——第一次循环就直接break了,完全没移动指针。更致命的是:当链表是空链表、只有1个节点或者2个节点时,temp2->next->next会直接访问空指针(比如单节点时,temp2=head,temp2->next是NULL,再取->next就触发SIGSEGV了)。
正确的快慢指针找中间节点逻辑应该是:快指针每次走2步,慢指针每次走1步,直到快指针走到链表末尾(快指针为NULL或者快指针的next为NULL)。
2. 奇数长度链表的拆分逻辑错误
原代码里判断奇数长度的条件搞反了:当快指针temp2->next == NULL时,说明链表是奇数长度,此时慢指针temp1指向的是中间节点,后半段应该从temp1->next开始,而不是temp1->next->next——这会直接跳过中间节点后的第一个节点,甚至再次触发空指针。
3. 修正后的完整可运行代码
#include <iostream> using namespace std; struct Node { int data; Node* next; Node(int val) : data(val), next(NULL) {} }; bool isPalindrome(Node *head) { // 处理边界情况:空链表或单节点链表直接是回文 if (head == NULL || head->next == NULL) { return true; } Node *slow = head; // 慢指针,最终指向中间节点附近 Node *fast = head; // 快指针,用于快速走到链表末尾 // 用快慢指针找到链表中间位置 while (fast != NULL && fast->next != NULL) { fast = fast->next->next; slow = slow->next; } // 如果是奇数长度链表,slow跳过中间节点(中间节点不影响回文判断) if (fast != NULL) { slow = slow->next; } // 反转后半段链表 Node *prev = NULL; Node *current = slow; Node *next = NULL; while (current != NULL) { next = current->next; current->next = prev; prev = current; current = next; } Node *secondHalf = prev; // 反转后的后半段头节点 Node *firstHalf = head; // 逐节点比较前后两段 while (secondHalf != NULL) { if (firstHalf->data != secondHalf->data) { return false; } firstHalf = firstHalf->next; secondHalf = secondHalf->next; } return true; } // 测试用例 int main() { // 奇数长度回文测试 Node* head1 = new Node(1); head1->next = new Node(2); head1->next->next = new Node(3); head1->next->next->next = new Node(2); head1->next->next->next->next = new Node(1); cout << (isPalindrome(head1) ? "True" : "False") << endl; // 输出True // 偶数长度回文测试 Node* head2 = new Node(1); head2->next = new Node(2); head2->next->next = new Node(2); head2->next->next->next = new Node(1); cout << (isPalindrome(head2) ? "True" : "False") << endl; // 输出True // 非回文测试 Node* head3 = new Node(1); head3->next = new Node(2); head3->next->next = new Node(3); cout << (isPalindrome(head3) ? "True" : "False") << endl; // 输出False return 0; }
关键修复点说明
- 先处理空链表/单节点的边界情况,从根源避免空指针访问;
- 正确实现快慢指针遍历:快指针走两步、慢指针走一步,确保准确找到中间节点;
- 奇数长度链表时,慢指针主动跳过中间节点(中间节点本身不影响回文判断);
- 反转后半段后,只需比较到后半段结束即可(前半段如果是奇数长度会多一个中间节点,无需比较);
内容的提问来源于stack exchange,提问作者Garvit
相关产品推荐
相关产品推荐

