J'ai l'algorithme de tri de fusion suivant qui fonctionne lorsque je teste avec 100, 1000 ou 10000 longues listes chaînées. Toutefois, il renvoie une erreur de segmentation sur la ligne contenant Node->Next=Merge(Front,Back->Next,Type);
lors de l'utilisation de 100 000 ou des listes liées long 1000000. Cela m'a amené à croire que c'est un débordement de pile plutôt qu'un défaut de segmentation. Selon gdb au moment de l'erreur, la pile est extraordinairement pleine. Je ne peux pas trouver un moyen d'examiner exactement combien d'éléments sont dans la pile d'appels pour donner un chiffre exact. Toute aide avec le tri de fusion de retravailler pour gérer de grandes quantités de données serait grandement appréciée.Comment empêcher le débordement de la pile lors de l'utilisation du tri par fusion sur de grandes quantités de données?
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);
arrêt utiliser la récursivité pour fusionner des listes; faites-le de manière itérative. – user2357112
Eh bien, vous pouvez le bloquer dans votre fichier hosts, vous pouvez utiliser une application de contrôle parental ... Oh! Vous vouliez dire un débordement de pile * littéral *! Eh bien, dans ce cas, user2357112 a raison, vous avez probablement atteint la limite de récursivité. ;-) –
L'utilisation de la récursivité produit un code élégant, mais vous voyez de première main ici ses problèmes et ses limites. À la segfault (ou tout point d'arrêt) dans 'gdb' vous pouvez taper' bt' (abréviation de backtrace) et il affichera la pile d'appels ... ne peut pas dire _quiiite_ si vous le savez déjà. – yano