归并排序代码存在错误求助:请修复现有代码而非重写
归并排序代码问题排查与修复
我来帮你找出这段归并排序代码的问题,咱们直接针对现有代码修改,不重写完整逻辑:
问题分析
你的代码核心问题出在merge_them函数里,有两个关键错误导致输出完全错误:
- 循环逻辑错误+越界访问:原代码的
for循环不管左右子数组是否已经遍历完,都会持续进行比较,这会导致访问数组越界的非法内存(比如i超过m或者j超过r时,a[i]/a[j]是未定义的);同时循环次数也多了一次(k<=r-l+1会执行r-l+2次,而final数组长度只有r-l+1)。 - 缺少剩余元素复制逻辑:当其中一个子数组的元素已经全部放入
final数组后,没有把另一个子数组剩下的元素直接复制进去,导致大量元素未被正确合并。
修复后的代码
只需要修改merge_them函数即可,其他部分保持不变:
#include <stdio.h> void merge_them(int a[], int l, int m, int r) { int i=l, j=m+1; int final[r-l+1]; int p=0; // 先合并两个子数组都有剩余元素的部分 while (i <= m && j <= r) { if(a[i] < a[j]) { final[p] = a[i]; i++; } else { final[p] = a[j]; j++; } p++; } // 复制左边子数组剩余的元素 while (i <= m) { final[p] = a[i]; i++; p++; } // 复制右边子数组剩余的元素 while (j <= r) { final[p] = a[j]; j++; p++; } // 将合并后的数组复制回原数组 j=0; for( i=l; i<r+1; i++) { a[i] = final[j]; j++; } } void merge(int a[], int l, int r) { if(l<r) { int m = (l+r)/2; merge(a,l,m); merge(a,m+1,r); merge_them(a,l,m,r); } } int main() { int a[10] = {10,9,8,7,6,5,4,3,2,1}; merge(a,0,9); for(int i=0; i<10; i++) printf("%d ",a[i]); }
修改说明
- 把原来的
for循环改成while循环,仅在两个子数组都有剩余元素时进行比较,彻底避免越界访问。 - 添加两个独立的
while循环,分别处理左边或右边子数组剩余元素的复制,确保所有元素都被合并到final数组中。 - 去掉了冗余的
else if(a[i]>=a[j]),直接用else即可,逻辑更简洁。
运行这段修改后的代码,就能得到正确的排序结果:1 2 3 4 5 6 7 8 9 10
内容的提问来源于stack exchange,提问作者ghost
相关产品推荐
相关产品推荐

