Я пытаюсь найти способ сортировки по алфавиту связанного списка строк. Это то, что у меня есть до сих пор, оно компилируется, но сбой при выполнении. Я работаю над ним часами, но, похоже, не понимаю его. Команда cout в циклах while печатает, поэтому я думаю, что это сравнение отлично. Я чувствую, что это связь, которую я испортил. Это школьная работа, поэтому любой вход приветствуется! его ordreAlpha, который (предположительно) сортирует список.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cerrno>
struct Espion
{
std:: string name; /* nom de lespion(ne) */
Espion *next; /* pointeur sur le prochain espion */
} ;
Espion *sortAlpha(Espion*ptr)
{
Espion *cur = ptr;
Espion *tempo = NULL;
Espion *prev = NULL;
Espion *first = ptr;
Espion *last = NULL;
bool flag;
do{
flag = false;
while(cur->next != NULL){
tempo = cur->next;
if(cur->name.compare(tempo->name) > 0){
flag = true;// needs swap
cur->next = tempo->next;
tempo->next = cur;
if(prev != NULL)
prev->next = tempo;
if(prev == NULL)
first = tempo;
if(cur->next == NULL)
last = cur;
prev = cur;
cur = cur->next;
delete tempo;
}
else {
prev = cur;
cur = cur->next;
}
}
delete cur;
delete prev;
cur = first;
}while(flag == true);
return first;
}
void printList(Espion* ptr)
{
std::cout << "\n"<< std::endl;
while(ptr){
std::cout << ptr-> name << std::endl;
ptr = ptr->next;
}
std::cout << "\n"<< std::endl;
}
int main()
{
char fileName[] = "espion.txt";
std:: string infoEspion;
Espion *cur = NULL;
Espion *first = NULL;
Espion *last = NULL;
Espion *add = NULL;
std :: ifstream readFile;
readFile.open(fileName, std::ios::in);
if(!readFile.is_open()){
exit(EXIT_FAILURE);
}
while(std::getline(readFile, infoEspion))
{
if(first == NULL){ //head
add = new Espion;
add -> name = infoEspion.substr(0,30);
add -> next = NULL;
first = add;
cur = add;
last = add;
}
else
if(trouverNomListe(first, infoEspion.substr(0,30)) == false ) // adding only if not on the list already
{
add = new Espion;
add -> name = infoEspion.substr(0,30);
add -> next = NULL;
cur -> next = add;
last = add;
cur = add;
}
}
printList(first);
printList(sortAlpha(first));
readFile.close();
system("pause");
return 0;
}
Во второй раз вокруг вашего do.. while
loop, prec
будет по-прежнему иметь свое предыдущее значение (конец списка), поэтому, когда вы обнаружите, что вам придется поменять место, он привяжет конец вашего списка tempo
. Чтобы это исправить, сбросить prec
к NULL в верхней части do.. while
во do.. while
цикла.
Вы также должны проверить, что ptr
не является NULL, когда ordreAlpha
вызывается, поскольку вы в настоящий момент проверяете cour->suivant
когда cour
может быть NULL.
Редактирование: после отладки другая проблема заключается в том, что при обмене узлами вы также выполняете cur = cur->next
, что может привести к тому, что cur
будет NULL
что приведет к ошибке в вашем cur->next != NULL
состоянии cur->next != NULL
, В этом случае (когда вы поменялись местами) вы не хотите перемещать cur
на следующий узел. Вместо этого вам просто нужно убедиться, что prev
установлен на правильное значение и пусть ваш цикл продолжается с текущим узлом.
В вашем случае просто измените
prev = cur;
cur = cur->next;
delete tempo;
в
prev = tempo;
prec = NULL
вверху цикла или внизу сразу после cour = prem
.
Вы можете избежать тех операторов if, которые проверяют для prev == NULL с помощью указателя на указатель:
Espion **pprev; // pointer to cur or previous node next pointer
// ...
cur = first; // init current pointer (before the do while loop)
// ...
pprev = &cur; // init pprev (before the inner while loop)
// ...
*pprev = tempo; // update what was pointing to cur
pprev = &(tempo->next); // update what prev points to
Ваша функция sortAlpha не выделяет ничего, поэтому любые операции удаления в ней есть подозрительные и, вероятно, приведут к сбоям позже
afficherListe
иtrouverNomListe
есть.