自定义C++单链表反转函数运行异常 无法输出反转后链表
单链表值交换反转功能异常排查
问题复现代码
#include "bits/stdc++.h" using namespace std; struct ListNode { int val ; ListNode * next; ListNode( int c ) { val = c; next = NULL; } }; void traversal ( ListNode * head ) { ListNode*temp = head ; while ( temp != NULL) { cout << temp->val << " "; temp=temp->next; } cout<<endl; } ListNode* reverseList(ListNode* head) { ListNode * temp=head; ListNode *p=head; ListNode *x=NULL ; while( head->val != x-> val ) { while( temp->next != x) temp=temp->next; swap(head->val,temp->next->val); x=temp->next; head=head->next; temp= head ; } return p; } int main() { ListNode * head = new ListNode ( 10 ); head->next = new ListNode ( 20 ); head-> next -> next =new ListNode ( 30 ); head-> next -> next-> next =new ListNode ( 40 ); head-> next -> next-> next-> next =new ListNode ( 50 ); traversal ( head ) ; head = reverseList ( head ) ; traversal ( head ) ; return 0 ; }
异常表现
- 程序仅输出原始链表遍历结果:10 20 30 40 50
- 输出上述内容后程序直接终止,无反转链表的输出内容
故障根因
- 首轮循环空指针解引用直接崩溃:
reverseList函数内指针x初始赋值为NULL,外层while的判断条件第一时间执行x->val,属于对空指针的非法内存访问,会直接触发段错误导致程序终止,这是无法输出后续内容的核心原因。 - 循环终止条件设计错误:原逻辑用
head->val == x->val作为停止交换的判断标准存在两个问题:一是链表存在重复值时会提前误触发终止,二是偶数长度链表交换到中间位置时,两个待交换节点是相邻关系,不会出现节点值相等的相遇场景,会导致指针越界。 - 边界场景未做处理:原逻辑没有考虑链表长度为0、长度为1的特殊场景,传入这类链表时也会触发空指针访问。
修复方案
核心调整逻辑:
- 新增空链表、单节点链表的前置判断,直接返回原头节点
- 调整外层循环终止条件,用指针位置判断代替值判断:当头指针和当前尾节点重合(奇数长度遍历到中间节点)、或头指针的next是当前尾节点(偶数长度遍历到相邻待交换节点)时停止循环
- 修正指针遍历逻辑,避免空指针访问
ListNode* reverseList(ListNode* head) { // 空链表、单节点链表无需反转 if (head == NULL || head->next == NULL) { return head; } ListNode* temp = head; ListNode* p = head; ListNode* x = NULL ; while(true) { temp = head; // 找到当前未处理段的尾节点 while(temp->next != x) temp = temp->next; // 到达中间位置,终止交换 if (head == temp || head->next == temp) { break; } swap(head->val, temp->val); x = temp; head = head->next; } return p; }
修复后程序正常运行输出:
10 20 30 40 50 50 40 30 20 10
内容的提问来源于stack exchange,提问作者simple navi
相关产品推荐
相关产品推荐

