我正在Objective-C中实现merge-sort(下面的代码)
当我没有将变量“middle
”增加一个时,我很难理解为什么我的递归调用是一个无限循环。
所以[self sort:array fromLow:middle+1 toHigh:high]
;工作正常
但是[self sort:array fromLow:middle toHigh:high];
会将我的程序变成无限循环。
任何人都可以解释我为什么会这样吗?
在两种情况下都是if语句
if(high<=low)
{
return;
}
到达并执行,所以我认为我的程序将转到第3个语句(mergeLow:andHigh:andMiddle:inArray:andHelperArray :) 但事实并非如此。
排序方法:
-(void)sort:(NSMutableArray *)array fromLow:(unsigned long)low toHigh:(unsigned long) high{
if(high<=low) //recursive condition fullfilled
{
return;
}
unsigned long middle = low + (high - low)/2; //calculating middle element
[self sort:array fromLow:low toHigh:middle]; //(1)sort left
[self sort:array fromLow:middle+1 toHigh:high];//(2)sort right
[self mergeLow:low andHigh:high andMiddle:middle inArray:array andHelperArray:[array mutableCopy]];//(3) merge left and right
}
调试 我试着调试它。为此,我将call(3)注释掉了merge方法,并添加了高和低变量的nslog语句记录值。
MergeSort *is = [MergeSort new];
NSArray * a1 = @[@10,@9,@22,@5];
[is sort:a1.mutableCopy fromLow:0 toHigh:a1.count];
更新了排序方法
-(void)sort:(NSMutableArray *)array fromLow:(unsigned long)low toHigh:(unsigned long) high{
//recursive condition fullfilled
NSLog(@"High: %lu Low %lu ",high, low);
if(high<=low)
{
return;
}
unsigned long middle = low + (high - low)/2;
[self sort:array fromLow:low toHigh:middle];
[self sort:array fromLow:middle + 1 toHigh:high];
// [self mergeLow:low andHigh:high andMiddle:middle inArray:array andHelperArray:[array mutableCopy]];
}
调试输出:中+ 1
2013-10-28 11:37:21.484 Algorithms[52598:303] High: 4 Low 0
2013-10-28 11:37:21.486 Algorithms[52598:303] High: 2 Low 0
2013-10-28 11:37:21.486 Algorithms[52598:303] High: 1 Low 0
2013-10-28 11:37:21.487 Algorithms[52598:303] High: 0 Low 0
2013-10-28 11:37:21.487 Algorithms[52598:303] High: 1 Low 1
2013-10-28 11:37:21.488 Algorithms[52598:303] High: 2 Low 2
2013-10-28 11:37:21.488 Algorithms[52598:303] High: 4 Low 3
2013-10-28 11:37:21.488 Algorithms[52598:303] High: 3 Low 3
2013-10-28 11:37:21.489 Algorithms[52598:303] High: 4 Low 4
现在在同一方法中,我执行[self sort:array fromLow:middle toHigh:high];
而不增加middle
变量并得到以下输出:
调试输出:中间
2013-10-28 11:45:55.689 Algorithms[52674:303] High: 4 Low 0
2013-10-28 11:45:55.691 Algorithms[52674:303] High: 2 Low 0
2013-10-28 11:45:55.691 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.692 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.692 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.693 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.693 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.693 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.694 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.694 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.694 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.695 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.695 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.696 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.696 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.696 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.697 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.697 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.698 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.698 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.699 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.699 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.699 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.700 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.700 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.700 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.701 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.701 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.702 Algorithms[52674:303] High: 1 Low 0
2013-10-28 11:45:55.702 Algorithms[52674:303] High: 0 Low 0
2013-10-28 11:45:55.702 Algorithms[52674:303] High: 1 Low 0
答案 0 :(得分:3)
您在两个调用中都包含中间元素('left'和'right')。
如果你只有2个元素,那么0和1,你得到的中间元素为0.5,其中0为int,你将'left'定义为[0],将'right'定义为[0 ,1],所以'正确'最终成为你在开始时拥有的东西。
这就是为什么如果你将'righ't定义为从中间+ 1开始你没有得到它。因为“左”将上升到中间,“右”将立即开始。他们没有任何共同点。
编辑(更多信息):
在使用递归算法时,您应始终牢记的一个概念是,只有在每次调用递归函数时,才能保证终止,您已经以某种方式将问题简化为比以前更简单的实例。
通常做的是你定义一种可以与递归函数的每次调用相关的度量,然后你证明每次调用都会减少这个量度。如果您知道在终止条件下该度量应该具有一定值,您现在可以确定问题最终将减少到终止条件并结束。
在这种情况下,您可以用作度量的是您要订购的数组的大小。您必须保证对递归函数的每次调用都将采用比调用它更小的数组。 如果数组的右边部分最终被调用的大小与原始部分相同,那么你就失败了。