Advertisement
Toliak

lab6_2

Nov 4th, 2018
373
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.58 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <iomanip>
  4.  
  5. struct Student
  6. {
  7.     std::string name;
  8.     std::string group;
  9.     unsigned short book;
  10.     unsigned short marks[4];
  11. };
  12.  
  13. struct ListNode
  14. {
  15.     Student value;
  16.     ListNode *prev = nullptr;
  17.     ListNode *next = nullptr;
  18. };
  19.  
  20. struct List
  21. {
  22.     ListNode *front = nullptr;
  23.     ListNode *back = nullptr;
  24. };
  25.  
  26. int pushListStudent(List *const list, Student &&student)
  27. {
  28.     if (list->front == nullptr) {   // Элементы в списке отсутствуют
  29.         list->front = new ListNode({
  30.                                        std::forward<Student>(student)
  31.                                    });       // Создаем
  32.         list->back = list->front;
  33.     } else {
  34.         ListNode *last = list->back;
  35.         list->back = new ListNode({
  36.                                       std::forward<Student>(student)
  37.                                   });
  38.  
  39.         list->back->prev = last;                // Линковка
  40.         last->next = list->back;
  41.     }
  42.     return 0;
  43. }
  44.  
  45. // Освобождение памяти
  46. int destroyList(List *const list)
  47. {
  48.     for (ListNode *current = list->front; current != nullptr; current = current->next) {
  49.         delete current->prev;   // Освобождение предыдущего
  50.     }
  51.     delete list->back;          // Освобождение последнего
  52.     list->front = list->back = nullptr; // Очистка
  53.     return 0;
  54. }
  55.  
  56. int swap(ListNode *const first, ListNode *const second, List *const list)
  57. {
  58.     if (first == second)
  59.         return 0;
  60.  
  61.     // Копируем указатели, чтобы анализировать их
  62.     // даже после перезаписи
  63.     ListNode *firstPrev = first->prev;
  64.     ListNode *firstNext = first->next;
  65.     ListNode *secondPrev = second->prev;
  66.     ListNode *secondNext = second->next;
  67.  
  68.     // Перелинковываем указатели у вершин
  69.     // (Меняем друг с другом)
  70.     // Если вершины рядом, то нужно линковать соседей
  71.     first->prev = (firstNext == second) ? second : second->prev;
  72.     first->next = (firstPrev == second) ? second : second->next;
  73.     second->prev = (secondNext == first) ? first : firstPrev;
  74.     second->next = (secondPrev == first) ? first : firstNext;
  75.  
  76.     // Теперь правильно ликнуем те вершины, которые ссылались на first и second
  77.     if (first->prev)
  78.         first->prev->next = first;
  79.     if (first->next)
  80.         first->next->prev = first;
  81.     if (second->next)
  82.         second->next->prev = second;
  83.     if (second->prev)
  84.         second->prev->next = second;
  85.  
  86.     // Обновляем поля списка, если это нужно
  87.     if (second->next == nullptr)
  88.         list->back = second;
  89.     else if (second->prev == nullptr)
  90.         list->front = second;
  91.     if (first->next == nullptr)
  92.         list->back = first;
  93.     else if (first->prev == nullptr)
  94.         list->front = first;
  95.  
  96.     return 0;
  97. }
  98.  
  99. // Сортировка
  100. void sort(List *const list)
  101. {
  102.     // Своеобразный цикл для обхода списка
  103.     for (ListNode *current = list->front; current != nullptr; current = current->next) {
  104.         ListNode *minimum = current;
  105.         for (ListNode *inside = current; inside != nullptr; inside = inside->next) {
  106.             if (inside->value.name < minimum->value.name) {
  107.                 minimum = inside;
  108.             }
  109.         }
  110.  
  111.         swap(minimum, current, list);
  112.         current = minimum;              // Минимум переместится на место current
  113.         // И будет левее
  114.     }
  115. }
  116.  
  117. int main()
  118. {
  119.     List mainList;
  120.  
  121.     size_t amount;                                   // Размер списка
  122.     std::cin >> amount;
  123.     for (size_t i = 0; i < amount; i++) {
  124.         Student student;
  125.  
  126.         std::cin.ignore();                      // Костыль
  127.         std::cout << "[S " << std::setw(3) << i << "] Name  : ";
  128.         std::getline(std::cin, student.name);         // Ввод
  129.         std::cout << "[S " << std::setw(3) << i << "] Group : ";
  130.         std::getline(std::cin, student.group);
  131.         std::cout << "[S " << std::setw(3) << i << "] Book  : ";
  132.         std::cin >> student.book;
  133.         for (size_t j = 0; j < 4; j++) {
  134.             std::cout << "[S " << std::setw(3) << i
  135.                       << "] Mark(" << j << "): ";
  136.             std::cin >> student.marks[j];
  137.         }
  138.  
  139.         pushListStudent(&mainList, std::move(student));
  140.     }
  141.  
  142.     sort(&mainList);              // Сортируем
  143.     // Своеобразный цикл для обхода списка
  144.     for (ListNode *current = mainList.front; current != nullptr; current = current->next) {
  145.         static size_t counter = 0;    // Счетчик
  146.         std::cout << "[S " << std::setw(3) << counter
  147.                   << "] Name  : " << current->value.name
  148.                   << std::endl;
  149.         std::cout << "[S " << std::setw(3) << counter
  150.                   << "] Group : " << current->value.group
  151.                   << std::endl;
  152.         std::cout << "[S " << std::setw(3) << counter
  153.                   << "] Book  : " << current->value.book
  154.                   << std::endl;
  155.         for (size_t j = 0; j < 4; j++)
  156.             std::cout << "[S " << std::setw(3) << counter
  157.                       << "] Mark(" << j << "): "
  158.                       << current->value.marks[j] << std::endl;
  159.         counter++;
  160.     }
  161.  
  162.     destroyList(&mainList);
  163.     return 0;
  164. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement