修改归并排序merge函数index为0、k=0后结果出错的问题排查
归并排序中Merge函数索引错误的原因与修复方案
咱们直接来拆解你遇到的问题:把merge函数里的index改成0,还加了k=0后排序结果出错,本质是索引逻辑混乱导致的,咱们一步步说清楚:
问题根源
归并排序里的merge函数,核心是把两个有序子数组合并到临时数组temp,再把temp里的有序元素复制回原数组的[l, r]区间。你的错误出在两个关键点:
index初始化为0的逻辑错误
原代码里index应该对应原数组的起始位置l,但你改成0后,temp从下标0开始存数据,最后复制回原数组时,会把合并后的元素覆盖原数组的前r-l+1个位置,而不是精准覆盖需要排序的[l, r]区间——这会直接打乱原数组中其他已经排好序的部分,或者把未排序的元素覆盖掉,自然得到错误结果。冗余变量
k引发的逻辑冲突
你声明了k但没给出完整代码,但如果同时用index和k控制temp的索引,很容易出现索引操作冲突,比如两个变量同时修改temp的位置,或者复制回原数组时用错了索引,进一步加剧排序混乱。
看你给出的代码片段:
void merge(int a[],int l,int m,int r){ int i=l,j=m+1,index=1,temp[size],k;//HERE while((i<=m) && (j<=r)...
这里index初始化为1本身就是错的(应该是l),改成0后错误更明显。
修复方案
正确的merge函数要保证:临时数组的元素最终能精准复制回原数组的[l, r]区间,下面给两种常用的正确实现:
方案1:临时数组从0开始索引(推荐)
这种方式逻辑更清晰,temp作为独立临时数组从0开始存元素,最后通过循环把内容映射回原数组的目标区间:
void merge(int a[],int l,int m,int r){ int i = l, j = m + 1; int temp[size]; int k = 0; // 临时数组从0开始计数 // 合并两个有序子数组到temp while(i <= m && j <= r){ if(a[i] <= a[j]){ temp[k++] = a[i++]; } else { temp[k++] = a[j++]; } } // 复制左半部分剩余元素 while(i <= m){ temp[k++] = a[i++]; } // 复制右半部分剩余元素 while(j <= r){ temp[k++] = a[j++]; } // 把temp的有序元素复制回原数组的[l, r]区间 for(i = l, k = 0; i <= r; i++, k++){ a[i] = temp[k]; } }
方案2:临时数组索引与原数组对齐
如果你想让temp的索引和原数组的目标区间对应,那index要初始化为l,最后直接覆盖原数组对应位置:
void merge(int a[],int l,int m,int r){ int i = l, j = m + 1; int temp[size]; int index = l; // 索引和原数组目标区间起始位置对齐 while(i <= m && j <= r){ if(a[i] <= a[j]){ temp[index++] = a[i++]; } else { temp[index++] = a[j++]; } } while(i <= m){ temp[index++] = a[i++]; } while(j <= r){ temp[index++] = a[j++]; } // 直接复制回原数组对应位置 for(i = l; i <= r; i++){ a[i] = temp[i]; } }
关键提醒
- 不管用哪种实现,核心是不要乱覆盖原数组中不需要更新的位置,必须保证临时数组的元素和原数组的
[l, r]区间一一对应。 - 不要同时用多个变量控制临时数组的索引,避免逻辑混乱,选一个变量(比如
k或index)统一操作就好。
内容的提问来源于stack exchange,提问作者Daksh Sharma
相关产品推荐
相关产品推荐

