归并排序的易错点

作者在实现归并排序时遇到问题,代码无法输出结果。问题在于函数`merge`中的`len`计算错误,因为数组作为参数传递时,`sizeof`返回的是指针大小而非数组长度。修正后的代码加入`len`参数以解决此问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在写归并排序时,代码感觉没什么毛病,但却跑不出结果来,不得其解,感觉流程并没什么毛病。

void merge(int *a, int left, int mid, int right)
{
    int len = sizeof(a) / sizeof(a[0]);
    int temp[len];
    int l = left;
    int m = mid + 1;
    int i = left;

    while (l <= mid && m <= right)
    {
        if (a[l] < a[m])
        {
            temp[i++] = a[l++];
        }

        else
        {
            temp[i++] = a[m++];
        }
    }

    while (l <= mid)
    {
        temp[i++] = a[l++];
    }

    while (m <= right)
    {
        temp[i++] = a[m++];
    }

    while (left <= right)
    {
        a[left] = temp[left];
        left++;
    }
}

void merge_sort(int *a, int left, int right)
{
    if (left < right)
    {

        int mid = (right + left) / 2;
        merge_sort(a, left, mid);
        merge_sort(a, mid + 1, right);
        merge(a, left, mid, right);
    }
}

代码和课本上基本没有区别,但是一运行就是不输出结果,直接停了。室友说可能出现了死循环,归并经常有这种情况。

后来,我调试了下代码,发现问题出在merge里的len。当数组作为函数参数传递时,它会被解析为指针。因此,在merge函数内部,a被视为一个指向整数的指针,而不是一个数组。所以,sizeof(a)实际上返回的是指针的大小(4字节或8字节),而不是数组的大小。

所以len要作为一个参数提前传入归并函数中,而不是在函数内用sizeof计算,或者不用数组,直接用vector形式,就省掉了这个麻烦。

修正代码如下:

void merge(int *a, int left, int mid, int right, int len)
{
    int temp[len];
    int l = left;
    int m = mid + 1;
    int i = left;

    while (l <= mid && m <= right)
    {
        if (a[l] < a[m])
        {
            temp[i++] = a[l++];
        }

        else
        {
            temp[i++] = a[m++];
        }
    }

    while (l <= mid)
    {
        temp[i++] = a[l++];
    }

    while (m <= right)
    {
        temp[i++] = a[m++];
    }

    while (left <= right)
    {
        a[left] = temp[left];
        left++;
    }
}

void merge_sort(int *a, int left, int right, int len)
{
    if (left < right)
    {

        int mid = (right + left) / 2;
        merge_sort(a, left, mid, len);
        merge_sort(a, mid + 1, right, len);
        merge(a, left, mid, right, len);
    }
}

看似简单,但是也足够细节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来年呢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值