You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义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
  • 输出上述内容后程序直接终止,无反转链表的输出内容

故障根因

  1. 首轮循环空指针解引用直接崩溃:reverseList函数内指针x初始赋值为NULL,外层while的判断条件第一时间执行x->val,属于对空指针的非法内存访问,会直接触发段错误导致程序终止,这是无法输出后续内容的核心原因。
  2. 循环终止条件设计错误:原逻辑用head->val == x->val作为停止交换的判断标准存在两个问题:一是链表存在重复值时会提前误触发终止,二是偶数长度链表交换到中间位置时,两个待交换节点是相邻关系,不会出现节点值相等的相遇场景,会导致指针越界。
  3. 边界场景未做处理:原逻辑没有考虑链表长度为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 19:39:14