为什么我的基本情况会立即(错误地)触发?

Why is my base case being (erroneously) triggered immediately?

提问人:Turboninja99 提问时间:1/25/2020 最后编辑:Turboninja99 更新时间:1/25/2020 访问量:38

问:

我正在尝试在 C 中实现合并排序算法。在递归数组拆分函数中,尽管有 return 语句,但我的基本情况是无限发生的,并且从未调用过合并函数。这是我的代码:

#include <stdio.h>

const int MAX = 1000;

int getArray(int unsorted[MAX], int upperBound)
{
    int i;
    for(i = 0; i <= upperBound; ++i)
    {
        printf("Now enter integer number %d: ", i + 1);
        scanf("%d", &unsorted[i]);
        while((getchar()) != '\n');
    }   
    printf("\n");
    return 0;
}

int merge(int unsorted[MAX], int sorted[1000], int lowerLeft, int lowerRight)
{
    if(lowerLeft == lowerRight)
        return 0;
    int j = lowerRight;
    for(int i = lowerLeft; i < lowerRight; ++i)
    {
        if(unsorted[i] <= unsorted[j])
        {
            sorted[i] = unsorted[i];
            ++j;
        }
        else
        {
            sorted[i] = unsorted[j];
            ++j;
        }
    }
    return 1;
}

int split(int unsorted[MAX], int sorted[1000], int lowerBound, int upperBound)
{
    printf("%d is the lBound and %d is the uBound\n", lowerBound, upperBound);
    if(lowerBound == upperBound)
    {
        printf("\nBase case triggered.");
        getchar();
        return 0;
    }
    int middle = upperBound/2;
    split(unsorted, sorted, 0, middle);
    split(unsorted, sorted, middle + 1, upperBound);    
    merge(unsorted, sorted, lowerBound, middle);
    return 1;
}

int main()
{
    int unsorted[MAX];
    int sorted[MAX];
    int lowerBound = 0;
    int upperBound;

    printf("First enter the number of integers you wish to sort: ");
    scanf("%d", &upperBound);
    while((getchar()) != '\n');
    printf("\n");
    upperBound = upperBound - 1;
    getArray(unsorted, upperBound);
    split(unsorted, sorted, lowerBound, upperBound);
    printf("\n");
    for(int c = 0; c < upperBound; ++c)
    {
        printf("%d, ", sorted[c]);
    }

    return 0;
}

为什么到达基本情况后不调用合并函数?对不起,如果我没有方便地表达这个问题,希望有人能在这里帮助我,谢谢。

C 递归 堆栈帧 指针别名

评论

1赞 user3386109 1/25/2020
在递归函数的顶部放置一个右键,并打印传递给函数的参数,即下限和上限,通常会有所帮助。然后,您将看到基本情况不会立即被触发。printf
0赞 user3629249 1/25/2020
OT:关于语句:在函数中:。还应该对 EOF 进行检查,类似于:'int ch;while((ch = getchar()) != '\n' && ch != EOF );while((getchar()) != '\n');main()
0赞 user3629249 1/25/2020
OT:关于:调用任何函数系列时,请始终检查返回值(而不是参数值)以确保操作成功。注意:这些函数返回成功的“输入格式转换说明符”的数量 建议: if( scanf(“%d”, &upperBound) != 1 ) { // 处理错误 }'scanf("%d", &upperBound);scanf()
0赞 user3629249 1/25/2020
关于; 表达式:是一个整数除法,整数除法总是去掉小数部分。函数:期望一个参数并返回一个值' 强烈建议完全删除对 (这也意味着头文件: 可以删除。注意:发布的代码不使用头文件中的任何内容,因此也可以删除头文件int middle = floor(upperBound/2);upperBound/2floor()doubledoublefloor()math.hstdlib.h
0赞 user3629249 1/25/2020
OT:发布的代码包含一些“神奇”的数字。“神奇”数字是没有根据的数字。即 1000。“神奇”数字使代码更难理解、调试等。建议使用一个或多个语句为这些“神奇”数字提供有意义的名称,然后在整个代码中使用这些有意义的名称enum#define

答:

1赞 Mark Snyder 1/25/2020 #1

您的基本情况被触发,因为这就是递归算法的工作方式。您一遍又一遍地调用,下限和上限之间的差距越来越小,因此最终触发了基本情况。这应该是一件好事,因为触发基本情况可以让你知道你的输入“数组”(单例)是排序的,可以合并。split()

它被“立即”触发的原因是它必须: split() 会不断被调用,直到满足基本情况,因此您将看到的第一个 print 语句是基本情况。

评论

0赞 Turboninja99 1/25/2020
感谢您的输入,user3629249。我添加了带有合并函数的更新代码,并完全删除了 floor 函数和数学库。我还在每个 printf 后添加了换行符。我还声明了一个名为 MAX 的常量全局整数。
0赞 Turboninja99 1/25/2020
谢谢 Mark,我采纳了 user3386109 的建议,并在递归函数的开头添加了一个 printf 语句。你是对的,基本情况不会立即触发,但是拆分函数继续无限递归,我不确定它为什么要这样做。你能给我指出正确的方向吗?谢谢