2015-11-12 3 views
0

Итак, я занимаюсь домашним заданием в структурах данных, и более двух часов я в тупике. Чтобы объяснить, мне нужно текстовые файлы ListJava и ListDS, где я беру информацию в формате: Имя Фамилия NUM. Оба файла содержат одни и те же имена, но не одинаковые. Назначение в основном требует от нас объединить сортировку файлов.C++ | Объединение списков ссылок

Это мои структуры:

typedef struct student 
{ 
    string name; 
    string surname; 
    int am; 
    int grade; 
}StudentFile; 
typedef struct node { 

    StudentFile element; 
    struct node* next; 
}Node; 

typedef struct stud 
{ 
    string name; 
    string surname; 
    int am; 
    int grade; 
    int grade2; 
    struct stud* next; 
}Student; 

А вот моя функция, где я их объединить:

/*Merge Lists into one*/ 
Student* MergeLists(Node* headDS, Node* headJava, Student* head) 
{ 
    bool flag = false; 

    Student *a = new Student; 
    Student *prev = NULL; 
    Student *temp = NULL; 
    Node *tempDS = headDS; 
    Node *tempJava = headJava; 
    Node *prevJava = NULL; 

    if (head == NULL) 
    { 
     head = a; //mermory alocation for head<Student> 
     temp = head; 
    // temp->next = NULL; 
    } 
    while (tempDS != NULL) 
    { 

     if(head != NULL) 
     { 

      if (tempDS->element.surname.compare(tempJava->element.surname) == 0) // if surnames are equal 
      { 
       prev = temp; 

       temp->name = tempDS->element.name; 
       temp->surname = tempDS->element.surname; 
       temp->am = tempDS->element.am; 
       temp->grade = tempDS->element.grade; 
       temp->grade2 = tempJava->element.grade; 

       tempJava = tempJava->next; 
       tempDS = tempDS->next; 
       temp = temp->next; 
       flag = false; //meaning that prevJava can get a new value again. 
      } 
      else // if DS > Java 
      { 
       /*Keep tempJava in mermory while iterating through the next nodes to find the temp that is equal to DS*/ 
       if (flag == false) 
       { 
        prevJava = tempJava; 
        tempJava = tempJava->next; 
        flag = true; 
       } 
       else 
       { 
        tempJava = tempJava->next; 
       } 

      } 

      /*temp = temp->next; 
      tempJava = tempJava->next; 
      tempDS = tempDS->next;*/ 
     } 
     prev->next = a; 
    } 
    a->next = NULL; 

    return a; 
} 

Проблема заключается в температуре = TEMP-> следующей строки. Хотя первый запуск совершенно нормально, а затем правильно ищет ListJava найти равное имя к значению ListDS Темп является 0xcdcdcdcd {...} и он бросает мне исключение:

Exception thrown at 0x00C38EF0 in Exercise3_zitima2.exe: 0xC0000005: Access violation reading location 0xCDCDCDE5. 

Как я противостоять этой ошибки , Я действительно искал вокруг судимых вещей здесь и там, но ничего не получается. Я знаю, что это не место, чтобы попросить кого-то решить мое задание, конечно, просто нужно небольшое руководство.

+0

Просто примечание, хотя оно работает, вам не нужно делать 'typedef struct student {} StudentFile; вместо этого вы можете сделать' struct StudentFile {}; '- он более понятен и работает почти так же. Об этом больше говорится в [этом сообщении] (http://stackoverflow.com/a/612350/887210). – ColGraff

+0

^Это действительно информативно! Спасибо за обмен :) – NickCh

ответ

3

Ваш Student структура не имеет конструктор, поэтому при выделении одного и назначить его a в MergeLists, a->next будет иметь мусор в нем. (The 0xCDCDCDCD что MSVC заполняет выделенную память с так что вы можете увидеть эти виды неинициализированного использования.)

Вы либо должны иметь конструктор установить next указатель на NULL или вручную установить его на NULL после выделения его.

+0

Приятная вещь знать о 0xCDCDCDCD. Итак, в структуре Студента, как это? : \t Студент() \t { \t \t next = NULL; \t} – NickCh

+0

@NickCh Еще лучше, используйте список инициализации конструктора: 'Student(): next (nullptr) {}' – vsoftco

+0

* sigh * Я попробовал еще ничего, так или иначе, я продолжу работу над вашими предложениями и посмотрю, что я могу do – NickCh

1

Функция списка слияний обычно используется для объединения двух уже отсортированных списков. Не задействовано распределение узлов. Первый узел из одного списка сравнивается с первым узлом другого списка. Меньший узел удаляется из его списка и добавляется к тому, что является изначально пустым списком, который в конечном итоге будет с объединенными узлами. Единственными членами узла, которые были изменены, являются следующие указатели. Процесс повторяется до тех пор, пока не будет достигнут конец одного из списков, а затем следующий указатель последнего узла, добавленного в объединенный список, будет установлен на первый узел остальной части другого списка, а слияние будет выполнено ,

+0

Я хотел сделать сортировку позже после того, как увидел, что работает текущий алгоритм. Хотя я полностью изменил его сейчас, сначала их отсортируйте, а затем объедините. – NickCh