对大型数组进行排序时出现快速排序错误
Posted
技术标签:
【中文标题】对大型数组进行排序时出现快速排序错误【英文标题】:Quicksort Error when sorting large array 【发布时间】:2017-01-07 03:33:27 【问题描述】:当我尝试对一个包含十万个整数的数组进行排序时收到一条错误消息(我已经测试过排序,它适用于五万个整数):
警告:无法加载任何 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;
【问题讨论】:
您几乎肯定会在这里看到堆栈溢出——这递归太深并导致不相关的内存损坏。您能否也发布您的迭代版本,以便我们可以看到它在做什么?另见***.com/questions/31431287/… 【参考方案1】:虽然快速排序本身被认为是一种递归算法,但分区步骤(您的comparetoPivot
方法)并不意味着递归。而且你对这个方法的实现不仅是递归的,而且就堆栈空间而言也是 O(N) 。每次递归到 compareToPivot 时,您只使用比以前少一个元素进行递归。由于默认堆栈约为 500KB,因此在大约 100K 元素时会发出爆炸(耗尽堆栈)的声音。
我以你的问题为借口来练习我的 Obj-C,我对此有点生疏。但这是直接从经典的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];
【讨论】:
我测试了代码,它可能没有工作可能有一些小错误或其他东西,但我只是添加了用于比较枢轴的迭代方法(在较小的数组上测试)。你的意思是(我很清楚)是因为我的比较方法是递归的,这就是错误发生的原因? @smcavoy19 - 我在上面修复了我的代码并对其进行了测试。现在应该可以工作了。是的,您的 compare 方法是递归的,并且保证需要多达 N 个堆栈递归。你的堆栈空间用完了。 感谢您的帮助。我也意识到我的迭代方法不正确,这就是为什么那个方法不起作用。我还发现,如果您有兴趣,可以在计算机上的设置中增加堆栈大小(我当然不会将其用于递归,但可能会用于更大的数组)。跨度>以上是关于对大型数组进行排序时出现快速排序错误的主要内容,如果未能解决你的问题,请参考以下文章