排序大型数组时出现Quicksort错误

时间:2017-01-07 03:33:28

标签: objective-c sorting

当我尝试对十万个整数的数组进行排序时,我收到一条错误消息(我已经测试了这种排序,它的工作量为五万):

  

警告:无法加载任何Objective-C类信息。这将显着降低可用类型信息的质量。

我也迭代地使用比较方法,并出现相同的错误

为什么会出现此错误消息?

是否可以对该列表进行排序,如果可以,如何解决?

-(void) quickSort{
   return [self quickSort:0 pivot:[self.toSort count]-1 right: [self.toSort count]-1];
}

-(void) quickSort:(int) left pivot:(int) pivot right:(int) right {
    if(left < right){
        pivot = [self compareToPivot:[[self.toSort objectAtIndex:right] intValue] start:left finish:right position:left];
        [self quickSort:pivot+1 pivot:pivot right:right];
        [self quickSort:left pivot:pivot right:pivot-1];
    }

}

-(int) compareToPivot:(int) pivot start:(int)start finish:(int)finish position:(int)pos{
    if(pos == finish){
        [self switchNums:start second:finish];
        return start;
    }
     if([[self.toSort objectAtIndex:pos] intValue] <= pivot){
     [self switchNums:pos second:start];
     return [self compareToPivot:pivot start:start+1 finish:finish position:pos+1];
}
return [self compareToPivot:pivot start:start finish:finish position:pos+1];
}

-(void) switchNums:(int)first second:(int)second{
    id temp = [self.toSort objectAtIndex:second];
    [self.toSort replaceObjectAtIndex:second withObject:[self.toSort objectAtIndex:first]];
    [self.toSort replaceObjectAtIndex:first withObject:temp];
}

迭代比较,运行良好:

-(int) compareToPivot:(int) pivot start:(int)start finish:(int)finish position:(int)pos{

while(pos != finish){
    if([[self.toSort objectAtIndex:pos] intValue] <= pivot){
        [self switchNums:pos second:start];
        start+=1;
    }
        pos++;
}
[self switchNums:start second:finish];
return start;

}

1 个答案:

答案 0 :(得分:1)

虽然Quicksort本身被认为是递归算法,但分区步骤(您的comparetoPivot方法)不适用于递归。而且你的这个方法的实现不仅是递归的,而且就堆栈空间而言它也是O(N)。每次递归到compareToPivot时,只需要比之前少一个元素。由于默认堆栈大约为500KB,所以预计会发出大约100K元素的声音(耗尽堆栈)。

我用你的问题作为练习我的Obj-C的借口,我有点生气。但这里是递归Quicksort的实现,直接来自经典Algorithms (Cormen et. al.) book并适用于您的toSort数组。我还没有全部测试过,但你肯定可以给它一个旋转。

-(int)partition: (NSMutableArray*)arr pivot:(int)pivot  right:(int)right
{
    int x = [[arr objectAtIndex: pivot] intValue];

    int i = pivot;
    int j = right;

    while (true)
    {

        while ([[arr objectAtIndex: j] intValue] > x)
        {
            j--;
        }

        while ([[arr objectAtIndex: i] intValue] < x)
        {
            i++;
        }

        if (i < j) {
            id objI = [arr objectAtIndex: i];
            id objJ = [arr objectAtIndex: j];
            [arr replaceObjectAtIndex:i withObject:objJ];
            [arr replaceObjectAtIndex:j withObject:objI];
            j--;
            i++;
        }
        else
        {
            return j;
        }
    }

}

-(void)quickSort
{
    int len = (int)[self.toSort count];
    [self quicksort:self.toSort left:0 right:(len-1)];
}

-(void)quicksort: (NSMutableArray*)arr left:(int)left  right:(int)right
{
    if (left< right)
    {
        int q = [self partition:arr pivot:left right:right];
        [self quicksort: arr left:left  right:q];
        [self quicksort: arr left:(q+1) right:right];
    }
}