我有以下合併排序算法,當我使用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);
停止:
如果你的編譯器不支持尾遞歸優化,你可以自己通過使函數體循環做使用遞歸合併列表;迭代地做。 – user2357112
那麼,你可以阻止它在你的主機文件中,你可以使用家長控制應用程序...哦!你的意思是*文字*堆棧溢出!那麼,在這種情況下,user2357112是正確的,你可能已經達到了遞歸限制。 ;-) –
使用遞歸產生優雅的代碼,但你在這裏看到的第一手它的麻煩和侷限性。在'gdb'中的segfault(或任何斷點)處,你可以輸入'bt'(縮寫爲backtrace),它將打印出調用堆棧...不能_quiiite_告訴你是否已經知道這一點。 – yano