Advertisement
Ver5us

C++ Stack example

May 23rd, 2019
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.17 KB | None | 0 0
  1. #include "pch.h"
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. /*------------------------------------------------------------------- СТЭК ---------------------------------------------------------------*/
  7.  
  8. /*
  9. Тип данных для стэка целых чисел Stack (последний пришёл - первый ушёл)
  10. @data - значение целого числа в элементе стэка
  11. @next - указатель на следующий элемент стэка (nullptr, если это элемент из основания стэка)
  12. */
  13. struct Stack
  14. {
  15.     int data;                           // поле данных
  16.     struct Stack* next;                 // указатель на следующий элемент cтэка
  17. };
  18.  
  19.  
  20.  
  21.  
  22. /*
  23. Операции над стэком Stack -----------------------
  24. В линейном списке мы использовали для доступа к оригинальному списку двойной указатель LinearList**, т.е. указатель на указатель на наш тип данных - вроде как (LinearList*)*,
  25. это было необходимо для того, чтобы в наших функциях можно было менять исходный список.
  26. Здесь используем альтернативный подход: будем прямо в функции явно ждать адрес передаваемого указателя (Stack* &top)
  27. Теперь чтобы менять исходные данные, нам можно передавать их в функцию как обычную переменную, что упрощает читабельность кода.
  28. */
  29.  
  30.  
  31. // добавление элемента значения @data = value в конец стэка
  32. void pushStack(Stack* &top, const int value)
  33. {
  34.     Stack* e = new Stack;               // объявляем новую динамическую переменную типа Stack и выделяем под неё память
  35.     e->data = value;                    // записываем в неё значение value, которое помещается в стэк
  36.     e->next = top;                      // связываем новый элемент стэка с предыдущим
  37.     top = e;                            // новый элемент стека становится его вершиной
  38. }
  39.  
  40. // извлечение значения из стэка с удалением верхнего элемента
  41. int popStack(Stack* &top)
  42. {
  43.     int tmp = top->data;                // извлекаем в переменную tmp значение в вершине стэка
  44.     Stack *e = top;                     // запоминаем указатель на вершину стэка, чтобы затем освободить выделенную под элемент e память
  45.     top = top->next;                    // вершиной становится предшествующий top элемент
  46.     delete e;                           // освобождаем память (удаляем извлеченную вершину стэка)
  47.     return tmp;                         // возвращаем значение, которое было в вершине стэка
  48. }
  49.  
  50. // Создание стэка top и инициализация его значениями на основе массива values длины length
  51. void createStack(Stack* &top, int* values, const int length)
  52. {
  53.     if (length > 0)                         // есть смысл инициализировать стэк толькое если передаваемая длина массива length ненулевая
  54.     {
  55.         for (int i = 0; i < length; i++)    // в цикле по массиву values...
  56.         {
  57.             pushStack(top, values[i]);      // Просто. Пушим. Их. В стэк.
  58.         }
  59.     }
  60. }
  61.  
  62. // Последовательный вывод содержимого стэка top (здесь нам не надо менять исходные данные, поэтому можно обойтись простым указателем на верхний элемент стэка Stack*)
  63. void printStack(Stack* top)
  64. {
  65.     cout << endl << "Стэк:" << endl;
  66.     Stack* e = top;                             // временная переменная e для обхода стэка с вершины до основания без извлечения (удаления) элементов
  67.     while (e != nullptr)                        // пока не достигнуто основание стэка, т.е. пока временная переменная e не приняла значение равное пустому указателю nullptr
  68.     {
  69.         cout << "[" << e->data << "] -> ";      // выводим данные из узла стэка @data
  70.         e = e->next;                            // сдвигаемся к основанию стэка
  71.     }
  72.     cout << "NULL" << endl;                     // основание стэка у нас всегда указывает на nullptr (NULL)
  73. }
  74.  
  75. // Очищаем стэк от элементов
  76. void clearStack(Stack* &top)
  77. {
  78.     while (top != nullptr)                      // пока стэк не опустеет
  79.     {
  80.         cout << top << " [" << top->data << "]" <<  endl;
  81.         popStack(top);                          // "выкидываем" элементы из стэка
  82.     }
  83. }
  84.  
  85.  
  86.  
  87. //-------------------------------------------------------------------------------//
  88. // Задача 2 лабораторной (по варианту 1)
  89. //-------------------------------------------------------------------------------//
  90. void operateStack(Stack* &top)
  91. {
  92.     cout << endl;
  93.     cout << "------------------------------------------------------" << endl;
  94.     cout << " Определение произведения нечётных значений элементов стека: " << endl;
  95.     cout << "------------------------------------------------------" << endl;
  96.  
  97.     int mul = 1;                                // произведение найденных элементов нечетных значений
  98.     int num = 0;                                // количество найденных элементов (просто для статистики и красоты вывода)
  99.  
  100.     if (top == nullptr)
  101.     {
  102.         cout << "Стэк пуст...";
  103.         return;
  104.     }
  105.  
  106.     cout << "Нечетные значения:" << endl;
  107.     while (top != nullptr)                      // пока не дошли до основания стэка
  108.     {
  109.         int pop = popStack(top);                // извлеваем верхнее значение...
  110.         if (pop % 2 != 0)                       // проверяем нечетность значения, извлеченного из стэка
  111.         {
  112.             cout << pop << endl;
  113.             mul *= pop;                         // если значение нечетное, перемножаем его с mul
  114.             num++;                              // ...и подсчитываем количество найденных элементов, удовлетворяющих условиям задачи
  115.         }
  116.     }
  117.    
  118.     if (num > 0)                                // если в результате обхода списка что-то нашлось, значит можно выводить произведение
  119.     {
  120.         cout << "Произведение нечетных значений = " << mul << endl;
  121.     }
  122.     else                                        // иначе считать особо нечего, не делить же 0 на 0...
  123.     {
  124.         cout << "Чисел удовлетворяющим условиям задачи в стэке не найдено" << endl;
  125.     }
  126. }
  127.  
  128.  
  129.  
  130. int main()
  131. {
  132.     setlocale(LC_ALL, "Russian");
  133.  
  134.     const int default_length = 5;                               // длина инициализационного массива
  135.     int default_data[default_length] = { 1, 4, 3, 44, 7 };      // инициализационный массив значений для инициализации структур
  136.  
  137.     Stack* stack = nullptr;                     // переменная для хранения указателя на вершину стэка
  138.  
  139.     cout << "------------------------------------------------------" << endl;
  140.     cout << " Создание стэка из массива [1,4,3,44,7]: " << endl;
  141.     cout << "------------------------------------------------------" << endl;
  142.     createStack(stack, default_data, default_length);
  143.     printStack(stack);
  144.  
  145.     cout << endl;
  146.     cout << "------------------------------------------------------" << endl;
  147.     cout << " Добавление элемента в стэк: " << endl;
  148.     cout << "------------------------------------------------------" << endl;
  149.  
  150.     int StackData = 0;
  151.     cout << "Введите целое число: ";
  152.     cin >> StackData;                           // записываем введенное число в переменную
  153.     pushStack(stack, StackData);
  154.     printStack(stack);
  155.  
  156.     cout << endl;
  157.     cout << "------------------------------------------------------" << endl;
  158.     cout << " Извлечение элемента из стэка: " << endl;
  159.     cout << "------------------------------------------------------" << endl;
  160.     popStack(stack);
  161.     printStack(stack);
  162.  
  163.     // задание лабораторной по варианту 1
  164.     operateStack(stack);
  165.  
  166.     cout << endl;
  167.     cout << "------------------------------------------------------" << endl;
  168.     cout << " УДАЛЕНИЕ всего стэка: " << endl;
  169.     cout << "------------------------------------------------------" << endl;
  170.  
  171.     clearStack(stack);
  172.     printStack(stack);
  173.  
  174.     return 0;
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement