【问题标题】:Merge Sort in C compiles, but doesn't sortC 中的合并排序可以编译,但不排序
【发布时间】:2011-02-06 04:52:28
【问题描述】:

我制作了这个程序来对数组进行排序。它工作正常,但它不会排序!请帮我找出我的逻辑中的错误。谢谢

[更新] 它能够工作!我只是按照下面的建议降低了 i、j 和 k。另外,从 i

#include <stdio.h>
#include <stdlib.h>

void mergesort(int[], int, int);
void merge(int [], int low, int mid, int hi); //function prototype

int main()
{
    int arr[]={1,4,78,92,9};
    mergesort(arr,0,5);
    //after mergesort
    for(int i=0; i<5; i++)
    {
        printf("%d, ", arr[i]);
    }
    system("pause");
    return 0;
}

void mergesort(int aptr[], int low, int hi)
{
    int mid =0;
    int rightmax=0;
    int leftmax=0;

    if(low==hi)
    {
        return;
    }
    mid=(low+hi)/2;
    mergesort(aptr, low, mid);
    mergesort(aptr, mid+1, hi);
    merge(aptr, low, mid, hi);
}

void merge(int aptr[], int low, int mid, int hi)
{
    int j, i, k;

    //copy contents of aptr to auxiliary b 
    for(i=low; i<=hi; i++)
    {
        bptr[i]=aptr[i]; 
    }

    // iterate through b as if they were still two arrays, lower and higher
    //copy smaller elements first
    i=low;
    j=mid+1;
    k=low;

    while(i<= mid && j<=hi)
    {
        if(bptr[i]<=bptr[j])//<--put smaller element first
        {
            aptr[k++]=bptr[i++];
        }
        else
        {
            aptr[k++]=bptr[j++];
        }
    } 
    // copy back first half just in case
    while(i<=mid)
    {
        aptr[k++]=bptr[i++];
    }
   }//function

【问题讨论】:

  • 程序不排序怎么能正常工作? ;-)
  • @Billy:我同意你的牙套风格。感谢您的编辑。 :-)
  • @Cody:去Allman style! :) 说真的,尽管我通常不会乱用样式,除非发布的代码 缺少 任何一致的样式。不过,非常欢迎您进行编辑。

标签: c recursion merge logic mergesort


【解决方案1】:

当您的程序执行时,语句 i&lt;= mid &amp;&amp; j&lt;=hi 永远不会为真,因此,永远不会进入依赖于它的 while 循环,并且永远不会到达实际交换元素的代码。

在它前面的for 循环之后,i 等于hi,它总是大于mid。我猜你的意思是在进入while 循环之前将i 重置为等于low

【讨论】:

    【解决方案2】:

    以下是关于如何开始的建议:将 printf() 调用放入您的 mergesort() 和 merge() 函数中,这些函数在每个函数调用的开始和返回时显示参数。这可能会帮助您弄清楚发生了什么。让其他人调试你的算法并不能帮助你学习如何编程。

    【讨论】:

    • 更好的是:使用真正的调试器,让您逐步观察变量和函数调用。使用printf 进行调试是一种相当笨拙的处理方式。
    • 在调试时寻求帮助是非常好的(而且通常是建设性的)。有时,如果你看一个函数足够长的时间,你就会对明显的问题视而不见。在这种情况下,第二组或第三组眼球确实很有帮助:) 我同意使用实际的调试器将是下一个合乎逻辑的步骤,我只是说...
    【解决方案3】:

    另外,我想提一下,您已经成为可能的整数溢出错误的受害者:

    mid=(low+hi)/2;
    

    如果low 和/或hi 足够大,low + hi 将溢出,从而为您提供错误的mid 值。相反,您应该这样做:

    mid = low + (hi - low) / 2;
    

    【讨论】:

    • 如果您对这些变量使用了size_t,那么在ptrdiff_tsize_t 具有相同大小(因此值位减少一个)的任何实际实现中,溢出不会可能。
    猜你喜欢
    • 1970-01-01
    • 2015-05-29
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多