我想知道它是如何工作的
I want to Know how its work
我想知道这个函数调用自身后发生了什么,它会恢复还是会继续调用自己直到条件变为 false
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);
}
}
it will keeping calling itself until condition became false
是的,这就是它的工作原理。
该算法采用范围 l
到 r
并将其分成两个范围并在每个范围上调用 mergesort
。
示例(为简短起见,我使用 ms 而不是 mergeSort)
初始调用系列:
ms(a, 0, 8) ---> ms(a, 0, 4) ---> ms(a, 0, 2) ---> ms(a, 0, 1) ---> ms(a, 0, 0)
由于值 0
和 0
不满足条件 l < r
因此调用将只是 return 和 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)
再一次,值 1
和 1
不满足条件 l < r
,因此调用将只是 return,在 merge
之后我们将 return 到先前的递归级别并在该级别对 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)
2
和 2
只是让我们 return 到上一个递归级别,其中 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 ...
另一种了解调用顺序的方法是添加一个 "recursion level" 并在调用 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
我想知道这个函数调用自身后发生了什么,它会恢复还是会继续调用自己直到条件变为 false
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);
}
}
it will keeping calling itself until condition became false
是的,这就是它的工作原理。
该算法采用范围 l
到 r
并将其分成两个范围并在每个范围上调用 mergesort
。
示例(为简短起见,我使用 ms 而不是 mergeSort)
初始调用系列:
ms(a, 0, 8) ---> ms(a, 0, 4) ---> ms(a, 0, 2) ---> ms(a, 0, 1) ---> ms(a, 0, 0)
由于值 0
和 0
不满足条件 l < r
因此调用将只是 return 和 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)
再一次,值 1
和 1
不满足条件 l < r
,因此调用将只是 return,在 merge
之后我们将 return 到先前的递归级别并在该级别对 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)
2
和 2
只是让我们 return 到上一个递归级别,其中 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 ...
另一种了解调用顺序的方法是添加一个 "recursion level" 并在调用 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