单链表冒泡排序代码触发段错误问题排查(需交换节点)
单链表冒泡排序(交换节点)段错误的修复方案
问题根源分析
你的代码触发段错误,核心问题集中在这几点:
- 头指针值传递导致更新失效:
sort_bubble函数接收的是头指针的副本,当排序中头节点被交换后,外部的head变量无法同步,后续操作会访问错误内存。 - 节点交换未处理前驱节点:仅交换相邻节点的指向,但没修改前驱节点的
next指针,直接导致链表断裂,触发空指针访问。 - 逻辑判断错误:
if(swapped = false)是赋值操作,不是相等判断,会错误终止排序循环,引发后续异常。 - 循环边界越界:内层循环条件
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
相关产品推荐
相关产品推荐

