Advertisement
Guest User

Untitled

a guest
Mar 29th, 2020
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.28 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. struct Item {
  6.     Item* next;
  7.     int data;
  8.  
  9.     Item(int value) // конструктор, для создания нового элемента
  10.     {
  11.         data = value;
  12.         next = this;
  13.     }
  14. };
  15. typedef Item* List;
  16.  
  17. List initEmptyList(); // инициализация пустого списка;
  18. List purgeList(List); // уничтожение списка с освобождением памяти;
  19. List addToHead(List, int); //добавление узла в голову списка;
  20. List addToTail(List, int); // добавление узла в хвост списка;
  21. List deleteFromHead(List); // удаление узла из головы списка;
  22. List deleteFromTail(List); // удаление узла из хвоста списка;
  23. void drawList (List); // выдача текущего списка на экран.
  24.  
  25. List firstSecondSwap(List); // Обмен первого узла и второго
  26. List removeFromPosition(List, int); // Удаление узла в указанной позиции
  27.  
  28. List initEmptyList()
  29. {
  30.     return nullptr; // nullptr - указатель на NULL
  31.     //если указатель на элемент списка равен nullptr, значит список пуст
  32.     // if (tail == nullptr) - проверка на пустоту
  33. }
  34.  
  35.  
  36. List addToHead(List tail, int value)
  37. {
  38.     if (tail == nullptr) return new Item(value); // список пуст, значит просто создаём элемент
  39.  
  40.     List p = new Item(value);
  41.     p->next = tail->next; // новый элемент указывает на голову
  42.     // Список циклический, поэтому любое tail->next - это начало списка
  43.     tail->next = p; // хвост указывает на новый элемент
  44.  
  45.     return tail;
  46. }
  47.  
  48. List addToTail(List tail, int value)
  49. {
  50.     // Добавляем в голову, и идём один раз вперёд
  51.     // Добавление в голову и в хвост осущетсвляется на одинаковые позиции в списке
  52.     // Между головой и хвостом
  53.     // Разница только в том, что при добавлении в голову, ты возвращаешь исходный указатель
  54.     // А при добавлении в хвост, следующий
  55.     tail = addToHead(tail,value);
  56.     tail = tail->next;
  57.     return tail;
  58. }
  59.  
  60. List deleteFromHead(List tail)
  61. {
  62.     if (tail == nullptr) return nullptr; // Список пустой, нечего удалять
  63.  
  64.     if (tail->next == tail) // Список из одного элемента
  65.     {
  66.         delete tail;
  67.         return nullptr;
  68.     }
  69.  
  70.     List tmp = tail->next; // сохраняем голову, делаем так, чтобы хвост указывал на следующий элемент
  71.     tail->next = tmp->next;
  72.  
  73.     // Голова теперь не принадлежит списку, её можно вычищать из памяти
  74.     delete tmp;
  75.  
  76.     return tail;
  77. }
  78.  
  79.  
  80. List deleteFromTail(List tail)
  81. {
  82.     if (tail == nullptr) return nullptr;
  83.  
  84.     if (tail->next == tail)
  85.     {
  86.         delete tail;
  87.         return nullptr;
  88.     }
  89.  
  90.     // Верхние два ифа как и в удалении с головы
  91.  
  92.     List tmp = tail;
  93.     while(tmp->next != tail) tmp = tmp->next; // идём до предпоследнего элемента
  94.  
  95.     tmp = deleteFromHead(tmp); // удаляем следующий за предпоследним элемент, теперь он - хвост списка
  96.  
  97.     return tmp; // возвращаем обновленный хвост
  98. }
  99.  
  100. List purgeList(List tail)
  101. {
  102.     while (tail != nullptr) tail = deleteFromHead(tail); // пока список не пустой, удаляем с головы
  103.  
  104.     return nullptr;
  105. }
  106.  
  107. List firstSecondSwap(List tail)
  108. {
  109.     // тут 3 частных случая, вынес их в отдельные ифы
  110.     if (tail == nullptr)  // список пустой, нечего удалять
  111.     {
  112.         drawList(tail);
  113.         return nullptr;
  114.     }
  115.  
  116.     if (tail->next == tail)// список из одного элемента, второго не существует
  117.     {
  118.         cout << "\nSecond element doesn't exist\n";
  119.         return tail;
  120.     }
  121.  
  122.     if (tail->next->next == tail) // Список из двух элементов, просто делаем сдвиг
  123.     {
  124.         return tail->next;
  125.     }
  126.  
  127.     // сохраняем первый и второй элементы
  128.     List tmp1 = tail->next; // первый элемент, или же хвост
  129.     List tmp2 = tmp1->next; // второй элемент
  130.  
  131.     // меняем порядок указателей
  132.     tmp1->next = tmp2->next; // первый указывает на третий
  133.     tmp2->next = tmp1; // второй указывает на первый
  134.     tail->next = tmp2; // хвост указывает на обновлённую голову, тоесть второй элемент
  135.  
  136.     return tail;
  137. }
  138.  
  139. List removeFromPosition(List tail,int position)
  140. {
  141.     if (tail == nullptr) // список пустой, удалять нечего
  142.     {
  143.         drawList(tail);
  144.         return nullptr;
  145.     }
  146.  
  147.     if (position < 0) // позиция меньше нуля, выводим ошибку
  148.     {
  149.         cout << "\nNegative position\n";
  150.         return tail;
  151.     }
  152.  
  153.     int size = 0;
  154.     List tmp = tail;
  155.     do
  156.     {
  157.         size++;
  158.         tmp = tmp->next;
  159.     } while (tmp != tail); // считаем размер списка
  160.    
  161.     if (position >= size) // слишком большая позиция
  162.     {
  163.         cout << "\nNo position\n";
  164.         return tail;
  165.     }
  166.  
  167.     // Индексация как в массивах
  168.     // тип у тебя список из четырех элементов и индексы: 0 1 2 3
  169.     if (position == 0) tail = deleteFromHead(tail); // нулевая позиция, удаляем с головы
  170.     else if (position == size-1) tail = deleteFromTail(tail); // последняя позиция, удаляем с хвоста
  171.     else
  172.     {
  173.         int counter = 0;
  174.         while (counter < position) // нам нужно добраться до элемента, который указывает на нужный нам
  175.         // если нужно удалить,допустим, третий, то мы добираемся до второго и уничтожаем следующий после него
  176.         {
  177.             tmp = tmp->next;
  178.             counter++;
  179.         }
  180.         tmp = deleteFromHead(tmp);
  181.     }
  182.  
  183.     return tail;
  184. }
  185. void drawList (List tail)
  186. {
  187.     if (tail == nullptr)
  188.     {
  189.         cout << "List has no elements...\n";
  190.         return;
  191.     }
  192.  
  193.     List tmp = tail->next;
  194.  
  195.     do
  196.     {
  197.         cout << tmp->data << ' ';
  198.         tmp = tmp->next;
  199.     } while (tmp != tail->next);
  200.  
  201.     return;
  202. }  
  203.  
  204. void commands()
  205. {
  206.     cout << "1) add number to list tail\n";
  207.     cout << "2) add number to list head\n";
  208.     cout << "3) delete list tail\n";
  209.     cout << "4) delete list head\n";
  210.     cout << "5) show list\n";
  211.     cout << "6) delete list\n";
  212.     cout << "7) remove value from position\n";
  213.     cout << "8) swap first and second\n";
  214.     cout << "9) command list\n";
  215.     cout << "0) exit\n";
  216.  
  217.     return;
  218. }
  219.  
  220. int main()
  221. {
  222.     List tail;
  223.     bool init = false;
  224.     commands();
  225.  
  226.     int command;
  227.     do
  228.     {
  229.         cout << "Write your command: ";
  230.         cin >> command;
  231.         if (!init && command != 10)
  232.         {
  233.             cout << "СПИСОК НЕ ИНИЦИАЛИЗИРОВАН\n";
  234.             continue;
  235.         }
  236.         switch (command)
  237.         {
  238.             int tmp;
  239.            
  240.            
  241.             case 1:
  242.                 cout << "Enter your number: ";
  243.                 cin >> tmp;
  244.  
  245.                 tail = addToTail(tail,tmp);
  246.                 break;
  247.             case 2:
  248.                 cout << "Enter your number: ";
  249.                 cin >> tmp;
  250.  
  251.                 tail = addToHead(tail,tmp);
  252.                 break;
  253.            
  254.             case 3:
  255.                 tail = deleteFromTail(tail);
  256.                 break;
  257.             case 4:
  258.                 tail = deleteFromHead(tail);
  259.                 break;
  260.            
  261.             case 5:
  262.                 cout << "\n" << "List: ";
  263.                 drawList(tail);
  264.                 break;
  265.            
  266.             case 6:
  267.                 tail = purgeList(tail);
  268.                 break;
  269.            
  270.             case 7:
  271.                 int position;
  272.                 cout << "Enter your position: ";
  273.                 cin >> position;
  274.  
  275.                 tail = removeFromPosition(tail,position);
  276.                 break;
  277.            
  278.             case 8:
  279.                 tail = firstSecondSwap(tail);
  280.                 break;
  281.            
  282.             case 9:
  283.                 commands();
  284.                 break;
  285.             case 10:
  286.                 tail = initEmptyList();
  287.                 init = true;
  288.                 break;
  289.             default:
  290.                 break;
  291.         }  
  292.     } while (command != 0);
  293.  
  294.     tail = purgeList(tail);
  295. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement