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

归并排序代码存在错误求助:请修复现有代码而非重写

归并排序代码问题排查与修复

我来帮你找出这段归并排序代码的问题,咱们直接针对现有代码修改,不重写完整逻辑:

问题分析

你的代码核心问题出在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]);
}

修改说明

  1. 把原来的for循环改成while循环,仅在两个子数组都有剩余元素时进行比较,彻底避免越界访问。
  2. 添加两个独立的while循环,分别处理左边或右边子数组剩余元素的复制,确保所有元素都被合并到final数组中。
  3. 去掉了冗余的else if(a[i]>=a[j]),直接用else即可,逻辑更简洁。

运行这段修改后的代码,就能得到正确的排序结果:1 2 3 4 5 6 7 8 9 10

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:37:38