【问题标题】:I want to Know how its work [closed]我想知道它的工作原理[关闭]
【发布时间】:2019-01-14 09:31:37
【问题描述】:

我想知道这个函数调用本身之后发生了什么是它会恢复还是会继续调用自己直到条件变为假

void mergeSort(int arr[], int l, int r)
{
    if (l < r)
    {
        // Same as (l+r)/2, but avoids overflow for
        // large l and h
        int m = l+(r-l)/2;

        // Sort first and second halves
        mergeSort(arr, l, m);
        mergeSort(arr, m+1, r);

        merge(arr, l, m, r);
    }
}

【问题讨论】:

  • 欢迎来到 SO。对于这样的小程序,您应该开始使用调试器。它将帮助您浏览代码并查看会发生什么。你也可以用纸笔执行指令。
  • 我不太明白你在问什么,但看来你可能正在寻找递归的基本解释(你可以在网上找到很多)。
  • @Gerhardh 不懂递归的人可能很难调试递归函数,甚至只是调试周期。
  • @Dukeling 这正是调试器中的会话可能会告诉您一千多个单词的情况。一遍又一遍地跨过相同的代码,也许查看调用堆栈可能会让您大开眼界,了解递归。也许 p&p 版本有点太难了,我同意。

标签: c algorithm sorting mergesort


【解决方案1】:

它会一直调用自己直到条件变为假

是的,它就是这样工作的。

该算法将lr 的范围分成两个范围,并在每个范围上调用mergesort

示例(为了简短起见,我使用 ms 而不是 mergeSort)

最初的一系列调用:

ms(a, 0, 8) ---> ms(a, 0, 4) ---> ms(a, 0, 2) ---> ms(a, 0, 1) ---> ms(a, 0, 0)

由于值00 不满足条件l &lt; r,因此调用将返回,并且将执行先前递归级别中mergeSort 的第二次调用。导致:

ms(a, 0, 8) ---> ms(a, 0, 4) ---> ms(a, 0, 2) ---> ms(a, 0, 1) ---> ms(a, 0, 0)
                                                                |
                                                                --> ms(a, 1, 1) 

再一次,11 的值不符合条件 l &lt; r,因此调用将返回,在 merge 之后,我们将返回上一个递归级别,并在第二次调用 mergeSort那个级别。

ms(a, 0, 8) ---> ms(a, 0, 4) ---> ms(a, 0, 2) ---> ms(a, 0, 1) ---> ms(a, 0, 0)
                                               |                |
                                               |                --> ms(a, 1, 1) 
                                               | 
                                               --> ms(a, 2, 2)

22 只是让我们回到之前的递归级别,第二次调用 mergeSort。我猜你现在看到图片了……

ms(a, 0, 8) ---> ms(a, 0, 4) ---> ms(a, 0, 2) ---> ms(a, 0, 1) ---> ms(a, 0, 0)
             |                |                |                |
             |                |                |                --> ms(a, 1, 1) 
             |                |                | 
             |                |                --> ms(a, 2, 2)
             |                |
             |                --> ms(a, 3, 4) ---> ms(a, 3, 3)
             |                                 |
             |                                 --> ms(a, 4, 4)
             |
             --> ms(a, 5, 8) ---> ... finish this your self ...

另一种理解调用顺序的方法是添加一个“递归级别”并在调用mergeSort 时进行一些简单的打印:

#include <stdio.h>

void mergeSort(int arr[], int l, int r, int level)
{
  printf("Recursion level %d l=%d r=%d\n", level, l, r);
    if (l < r)
    {
        // Same as (l+r)/2, but avoids overflow for
        // large l and h
        int m = l+(r-l)/2;

        // Sort first and second halves
        mergeSort(arr, l, m, level+1);
        mergeSort(arr, m+1, r, level+1);

        // merge commented out as it is irrelevant for the call sequence
        // merge(arr, l, m, r);
    }
}

int main()
{
  int a[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
  mergeSort(a, 0, 8, 0);
  return 0;
}

输出:

Recursion level 0 l=0 r=8
Recursion level 1 l=0 r=4
Recursion level 2 l=0 r=2
Recursion level 3 l=0 r=1
Recursion level 4 l=0 r=0
Recursion level 4 l=1 r=1
Recursion level 3 l=2 r=2
Recursion level 2 l=3 r=4
Recursion level 3 l=3 r=3
Recursion level 3 l=4 r=4
Recursion level 1 l=5 r=8
Recursion level 2 l=5 r=6
Recursion level 3 l=5 r=5
Recursion level 3 l=6 r=6
Recursion level 2 l=7 r=8
Recursion level 3 l=7 r=7
Recursion level 3 l=8 r=8

相同的输出,但具有依赖于级别的缩进:

Recursion level 0 l=0 r=8
  Recursion level 1 l=0 r=4
    Recursion level 2 l=0 r=2
      Recursion level 3 l=0 r=1
        Recursion level 4 l=0 r=0
        Recursion level 4 l=1 r=1
      Recursion level 3 l=2 r=2
    Recursion level 2 l=3 r=4
      Recursion level 3 l=3 r=3
      Recursion level 3 l=4 r=4
  Recursion level 1 l=5 r=8
    Recursion level 2 l=5 r=6
      Recursion level 3 l=5 r=5
      Recursion level 3 l=6 r=6
    Recursion level 2 l=7 r=8
      Recursion level 3 l=7 r=7
      Recursion level 3 l=8 r=8

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多