合并排序基本案例(递归)剖析
Merge Sort Base Case (Recursion) Dissect
摘自 Robert Sedgewick 和 Kevin Wayne 算法第 4 版
在递归部分基本案例代码是
if(end <= start)
{
return;
}
但我检查过 end
永远不会低于 start
指数。只有 end = start
只剩下 1 个元素时才会发生。那么为什么在只有一个等于 =
的条件始终有效的情况下使用 <=
小于运算符?
假设一个数组a[8,5,3]
被采用。
现在中间点是第一个索引所以除法后
a[8,5] and a[3]
divide(a,0,1) and divide(a,2,2), merge(a,0,1,2)
start is smaller than end in divide(a,0,1)
and start=end
happen in divide(a,2,2)
function call.
现在 mid 是第 0 个索引。
a[8] and a[5]
divide(a,0,0) and divide(a,1,1), merge(a,0,0,1)
here in both function call start=end
is only true.
所以从字面上看 end
永远不会小于 start
因此 end<start
永远不会发生。只有 end=start
发生。
谁能解释一下为什么我们在合并排序的基本情况下使用 <(小于)运算符?
完整的递归代码
int divide(int a[], int start, int end)
{
int mid;
if(end<=start)
{
return;
}
else
{
mid = (start+end)/2;
divide(a, start, mid);
divide(a, mid+1, end);
merge(a, start, mid, end);
}
}
divide
函数从不 使用参数调用自身是正确的,因此end < start
。因此,if 语句也可以是 if (end == start)
.
如果从 另一段 代码中以不正确的方式调用 divide 函数,例如
void foo(int a[])
{
divide(a, 5, 3);
}
如果您的检查只是 ==
而不是 <=
,那将导致无限循环。因此使用 <=
.
似乎更安全
原来的代码也可以这样重写:
int divide(int a[], int start, int end)
{
int mid;
if(end > start)
{
mid = (start+end)/2;
divide(a, start, mid);
divide(a, mid+1, end);
merge(a, start, mid, end);
}
}
在任何情况下,这可能对性能无关紧要 - 优化编译器无论如何都会重新安排。
BTW: Notice that your function is said to return an int but you don't do that. Maybe you really want it to be: void divide(.....)
你可以像下面这样编写函数 divide 的递归部分
void divide(int a[], int start, int end)
{
int mid;
if(start < end)
{
mid = (start+end)/2;
divide(a, start, mid);
divide(a, mid+1, end);
merge(a, start, mid, end);
}
}
摘自 Robert Sedgewick 和 Kevin Wayne 算法第 4 版
在递归部分基本案例代码是
if(end <= start)
{
return;
}
但我检查过 end
永远不会低于 start
指数。只有 end = start
只剩下 1 个元素时才会发生。那么为什么在只有一个等于 =
的条件始终有效的情况下使用 <=
小于运算符?
假设一个数组a[8,5,3]
被采用。
现在中间点是第一个索引所以除法后
a[8,5] and a[3]
divide(a,0,1) and divide(a,2,2), merge(a,0,1,2)
start is smaller than end individe(a,0,1)
andstart=end
happen individe(a,2,2)
function call.
现在 mid 是第 0 个索引。
a[8] and a[5]
divide(a,0,0) and divide(a,1,1), merge(a,0,0,1)
here in both function callstart=end
is only true.
所以从字面上看 end
永远不会小于 start
因此 end<start
永远不会发生。只有 end=start
发生。
谁能解释一下为什么我们在合并排序的基本情况下使用 <(小于)运算符?
完整的递归代码
int divide(int a[], int start, int end)
{
int mid;
if(end<=start)
{
return;
}
else
{
mid = (start+end)/2;
divide(a, start, mid);
divide(a, mid+1, end);
merge(a, start, mid, end);
}
}
divide
函数从不 使用参数调用自身是正确的,因此end < start
。因此,if 语句也可以是 if (end == start)
.
如果从 另一段 代码中以不正确的方式调用 divide 函数,例如
void foo(int a[])
{
divide(a, 5, 3);
}
如果您的检查只是 ==
而不是 <=
,那将导致无限循环。因此使用 <=
.
原来的代码也可以这样重写:
int divide(int a[], int start, int end)
{
int mid;
if(end > start)
{
mid = (start+end)/2;
divide(a, start, mid);
divide(a, mid+1, end);
merge(a, start, mid, end);
}
}
在任何情况下,这可能对性能无关紧要 - 优化编译器无论如何都会重新安排。
BTW: Notice that your function is said to return an int but you don't do that. Maybe you really want it to be: void divide(.....)
你可以像下面这样编写函数 divide 的递归部分
void divide(int a[], int start, int end)
{
int mid;
if(start < end)
{
mid = (start+end)/2;
divide(a, start, mid);
divide(a, mid+1, end);
merge(a, start, mid, end);
}
}