Objective-C中的无限递归调用

时间:2013-10-28 16:24:26

标签: objective-c recursion

我正在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 

1 个答案:

答案 0 :(得分:3)

您在两个调用中都包含中间元素('left'和'right')。

如果你只有2个元素,那么0和1,你得到的中间元素为0.5,其中0为int,你将'left'定义为[0],将'right'定义为[0 ,1],所以'正确'最终成为你在开始时拥有的东西。

这就是为什么如果你将'righ't定义为从中间+ 1开始你没有得到它。因为“左”将上升到中间,“右”将立即开始。他们没有任何共同点。

编辑(更多信息):

在使用递归算法时,您应始终牢记的一个概念是,只有在每次调用递归函数时,才能保证终止,您已经以某种方式将问题简化为比以前更简单的实例。

通常做的是你定义一种可以与递归函数的每次调用相关的度量,然后你证明每次调用都会减少这个量度。如果您知道在终止条件下该度量应该具有一定值,您现在可以确定问题最终将减少到终止条件并结束。

在这种情况下,您可以用作度量的是您要订购的数组的大小。您必须保证对递归函数的每次调用都将采用比调用它更小的数组。 如果数组的右边部分最终被调用的大小与原始部分相同,那么你就失败了。