C++链表Push操作后sortedInsert有序插入功能异常排查
问题根因
核心错误出在sortedInsert函数的遍历终止逻辑,push功能本身没有问题。
当前sortedInsert的遍历逻辑为:
Node* current = *head_ref; while(current->next!=NULL && current->data<new_node->data) { current=current->next; }
该判断逻辑的缺陷是:直接拿当前遍历节点的值和新节点值比较,只要当前节点值更小就向后移动指针,最终会停在「第一个值大于等于新节点的节点」位置;但有序插入要求指针停在「最后一个值小于新节点的节点」位置,再把新节点接在它后面,这就导致插入位置整体后移一位,无法放到正确位置。
可以通过最简单的场景复现问题:
- 初始输入起始值为5,链表为
5 -> NULL - 调用Push插入3,头插逻辑正常,链表变为
3 -> 5 -> NULL - 调用有序插入插入值4:
- 头节点值3 < 4,满足循环条件,指针后移到值为5的节点
- 此时5 >=4,退出循环,把4插在5后面,最终链表变成
3 ->5 ->4 ->NULL,完全不符合有序预期
修复方法
把遍历循环的判断条件从「比较当前节点值」改为「比较当前节点的下一个节点的值」,修改后代码如下:
void sortedInsert(Node** head_ref, int new_data) { Node* new_node=new Node(); new_node->data=new_data; new_node->next = NULL; if(*head_ref==NULL||(*head_ref)->data>=new_node->data) { new_node->next=*head_ref; *head_ref=new_node; return; } Node* current = *head_ref; // 修改判断条件:检查下一个节点的值,而非当前节点 while(current->next!=NULL && current->next->data < new_node->data) { current=current->next; } new_node->next=current->next; current->next=new_node; }
其他潜在问题(不触发本次插入错误,但可能引发其他异常)
main函数中char choice;声明后未初始化就进入while判断,属于未定义行为,建议声明时初始化为0- while循环条件
while (choice != 'Q'||choice !='Q')为恒真条件(单个字符不可能同时等于大写Q和小写q,或逻辑永远成立),虽然内部有break可以退出,但逻辑写法错误,可改为while(tolower(choice) != 'q') deleteList函数中用free()释放new申请的节点,属于未定义行为,C++中new需要配对delete释放,将free(current);改为delete current;即可- 代码中声明的
Node* sorted = NULL;从未被使用,属于冗余变量,且初始为其new的节点未被释放,存在内存泄漏 srand(time(NULL));写在循环内部,若用户快速输入非法选项,会因时间种子精度问题生成重复随机数,建议将srand放到main函数开头仅执行一次
内容的提问来源于stack exchange,提问作者user19546002
相关产品推荐
相关产品推荐

