【发布时间】:2018-02-08 18:47:46
【问题描述】:
当我使用 100、1000 或 10000 个长链表进行测试时,我有以下合并排序算法。但是,当使用 100000 或 1000000 个长链表时,它会在包含 Node->Next=Merge(Front,Back->Next,Type); 的行上返回分段错误。这让我相信这是堆栈溢出而不是分段错误。根据 gdb 在错误发生时堆栈非常满。我无法找到一种方法来准确检查调用堆栈中有多少项以给出准确的数字。任何有关修改合并排序以处理大量数据的帮助将不胜感激。
struct IntList
{
int Value;
int Frequency;
struct IntList* Next;
struct IntList* Prev;
};//Struct for Integer Linked List
void SortList(struct IntList** Values,enum SortBy Type)
{
struct IntList* Head = *Values;
if(Head==NULL||Head->Next==NULL)
{
return;
}//If Base Case
struct IntList* Front;
struct IntList* Back;
Split(Head,&Front,&Back);//Splits Linked List
SortList(&Front,Type);
SortList(&Back,Type);//Recursively Sorts
*Values=Merge(Front,Back,Type);//Merges Halves
return;
}
void Split(struct IntList* Head,struct IntList** Front,struct IntList** Back)
{
struct IntList* Fast;
struct IntList* Slow;
if (Head==NULL||Head->Next==NULL)
{
*Front=Head;
*Back=NULL;
}//If Length <2
else
{
Slow=Head;
Fast=Head->Next;
}
while(Fast!=NULL)
{
Fast=Fast->Next;
if(Fast!=NULL)
{
Fast=Fast->Next;
Slow=Slow->Next;
}
}//Find Midpoint
*Front=Head;
*Back=Slow->Next;
Slow->Next=NULL;//Breaks Link
return;
}
struct IntList* Merge(struct IntList* Front,struct IntList* Back,enum SortBy Type)
{
if(Front==NULL)
{
return Back;
}
if (Back==NULL)
{
return Front;
}//Base Cases
struct IntList* Node;
if(Type==DATA)
{
if(Front->Value <= Back->Value)
{
Node=Front;
Node->Next=Merge(Front->Next,Back,Type);
}
else
{
Node=Back;
Node->Next=Merge(Front,Back->Next,Type);
}//Takes Greatest Value for Sorted List
}//If Sorting by Data
if(Type==FREQUENCY)
{
if(Front->Frequency < Back->Frequency)
{
Node=Front;
Node->Next=Merge(Front->Next,Back,Type);
}
else
{
Node=Back;
Node->Next=Merge(Front,Back->Next,Type);
}//Takes Greatest Frequency for Sorted List
}//If Sorting by Frequency
return(Node);
【问题讨论】:
-
停止使用递归合并列表;迭代地做。
-
嗯,你可以在你的主机文件中阻止它,你可以使用家长控制应用程序......哦!你的意思是 literal 堆栈溢出!好吧,在这种情况下,user2357112 是对的,您可能已经达到了递归限制。 ;-)
-
使用递归可以产生优雅的代码,但是您在这里亲眼看到它的麻烦和局限性。在
gdb中的段错误(或任何断点)处,您可以输入bt(回溯的缩写),它会打印出调用堆栈...无法quiiite 告诉您是否知道这一点已经。
标签: c stack-overflow mergesort