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

单链表冒泡排序代码触发段错误问题排查(需交换节点)

单链表冒泡排序(交换节点)段错误的修复方案

问题根源分析

你的代码触发段错误,核心问题集中在这几点:

  1. 头指针值传递导致更新失效:sort_bubble函数接收的是头指针的副本,当排序中头节点被交换后,外部的head变量无法同步,后续操作会访问错误内存。
  2. 节点交换未处理前驱节点:仅交换相邻节点的指向,但没修改前驱节点的next指针,直接导致链表断裂,触发空指针访问。
  3. 逻辑判断错误:if(swapped = false)是赋值操作,不是相等判断,会错误终止排序循环,引发后续异常。
  4. 循环边界越界:内层循环条件j <= (count-2-i)会让最后一次循环访问NULL节点的data,触发段错误。

修复后的完整代码

#include<iostream>
using namespace std;   

typedef struct node
{
    int data;
    struct node *next;
} node;

node* create_node(node *head, int data)
{
    node *baby = (node*)malloc(sizeof(node));
    baby->data = data;
    baby->next = NULL;
    
    if(head==NULL)
        head = baby;
    else
    {
        node *curr = head;
        while(curr->next != NULL)
            curr = curr->next;
        curr->next = baby;  
    }
    return head;    
}

// 修改为传递头指针的指针,以便更新外部头节点
void sort_bubble(node **head)
{
    int count=0, i, j;
    bool swapped;
    node *prev, *curr, *tempo, *p1, *p2;
    
    // 统计节点数量
    for(curr=*head; curr!=NULL; curr=curr->next)
        count++;
    
    for(i=0; i<count-1; i++)
    {
        prev = NULL; // 追踪当前节点的前驱
        curr = *head;
        swapped = false;
        // 调整循环边界,避免访问NULL
        for(j=0; j<count-1-i; j++)
        {
            p1 = curr;
            p2 = p1->next;
            
            if(p1->data > p2->data)
            {
                tempo = p2->next;
                p2->next = p1;
                p1->next = tempo;
                
                // 更新前驱节点的指向
                if(prev == NULL)
                {
                    // 交换的是头节点,更新外部头指针
                    *head = p2;
                }
                else
                {
                    prev->next = p2;
                }
                
                prev = p2; // 前驱节点变为p2
                curr = p2; // 当前节点移动到p2
                swapped = true;
            }
            else
            {
                prev = curr; // 未交换时,前驱节点后移
            }
            curr = curr->next;
        }
        // 修正判断条件:没有交换则提前终止
        if(!swapped)
            break;
    }
}

void print_list(node *head)
{
    node *curr = head;
    while(curr)
    {
        cout<<curr->data<<" ";
        curr = curr->next;
    }
    cout<<"\n";
}

int main()
{
    node *head = NULL;
    
    head = create_node(head, 40);
    head = create_node(head, 10);
    head = create_node(head, 60);
    head = create_node(head, 50);
    head = create_node(head, 20);
    head = create_node(head, 30);
    print_list(head);
    
    // 传入头指针的地址
    sort_bubble(&head);
    print_list(head);
    
    return 0;
}

关键修改说明

  • 将sort_bubble的参数改为node** head,确保头节点变化时能同步到外部变量。
  • 添加prev指针追踪当前节点的前驱,交换节点时同步更新前驱的next指针,避免链表断裂。
  • 修正swapped的判断条件为if(!swapped),正确检测是否需要提前终止排序。
  • 调整内层循环的边界为j < count-1-i,防止访问NULL节点的成员。

内容的提问来源于stack exchange,提问作者Debbie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 17:05:32