Динамическая структура данных стек

Содержание:

Для лучшего понимания данного материала ознакомьтесь с кратким очерком о классификации динамических структур данных.

Я - репетитор, готовый помочь в реализации структуры данных стек

Здравствуйте! Меня зовут Александр Георгиевич. Я - профессиональный репетитор по информатике, математике, динамическим структурам данных и программированию. Уже на протяжении 10 лет я помогаю студентам технических вузов со всей России в реализации структуры данных стек. Реализацию провожу на выбор моих клиентов на одном из языков программирования: Pascal, Delphi, C, C++, C#, Basic, VBA.

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

По требованию клиента я могу детально прокомментировать программный код, а также записать видеокомментарий. Иногда студент приезжает ко мне домой за особыми разъяснениями.

А сейчас я предлагаю вашему вниманию видеоматериал, в котором я диференцированно поясняю все тонкие моменты нашего взаимовыгодного сотрудничества. Особое внимание обратите на отзывы клиентов под видео, заказавших у меня работу по программированию.

Что же такое структура данных "СТЕК"?

Структура данных стек - частный случай линейного односвязного списка (ЛОС), для которого определены две фундаментальные операции:

  1. Добавление элемента в вершину стека.

  2. Удаление элемента из вершины стека.

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

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

Указатель на вершину стека

Для корректной обработки элементов структуры данных стек вводят понятие - указатель на вершину стека. Как правило, именуется в программе подобный указатель словом top (в переводе с английского означает вершина, верхушка). Данный указатель обязан указывать или ссылаться только на самый верхний элемент стека, иначе стек будет находиться в несогласованном состоянии.

В программе на языке Pascal, декларация указателя на вершину стека выглядит примерно так:

  1. top : Tptr;

вы должны очень хорошо понимать, что собою представляет тип данных Tptr.

Организация взаимосвязей в связанных динамических данных

Любые динамические данные характеризуются высокой гибкостью создания различных структур данных всевозможных конфигураций. Это достигается благодаря возможности выделять и освобождать память под элементы в любой момент времени работы программы и возможности установить связь между любым набором элементов с помощью специальных указателей.

Для правильной организации связей между элементами динамической структуры данных требуется, чтобы каждый элемент содержал кроме информационных значений, как минимум, один указатель. Зачастую, в качестве информационных полей используют записи (в языке программирования Pascal именуются как Record), которые могут консолидировать в единое целое разнородные значения.

Рассмотрим объявление динамической структуры данных на языке программирования Pascal 7.0.:

  1. type
  2. {указательный тип данных на элемент Стека}
  3.     Tptr = ^Telem;
  4. {запись, состоящая из двух полей, описывающая элемент Стека}
  5.     Telem = record
  6.         inf : integer;  {информационное поле - хранит целые числа}
  7.         link : Tptr;    {указательное поле - ссылка на следующий элемент Стека}
  8.     end;

ВАЖНО!
Правило последовательности описаний в Pascal требует, чтобы каждый идентификатор был описан, прежде чем он будет использоваться для других объявлений. Если посмотреть на декларацию, представленную выше, то очевидно, что идентификатор Tptr имеет указательный тип данных Telem, но ведь Telem еще не объявлен. Однако, ошибки не возникает, так как для описания типов элементов динамических структур данных сделано исключение.

Операции, проводимые над стеком

Абсолютно во всех операциях, производимых над структурой данных стек, требуется вспомогательный указатель, помимо указателя top, ссылающего на вершину стека. Во всех программах и фрагментах программного кода, представленных ниже, будем обозначать вспомогательный указатель идентификатором p. Почему "p"? Потому что с английского слово pointer переводится на русский как указатель).

Рассмотрим операцию добавления элемента в вершину стека. Данная операция имеет две разновидности:

  1. Добавление элемента в стек, когда стек не содержит ни одного элемента.

  2. Добавление элемента в стек, когда стек к моменту добавления содержит определенное число элементов (добавленных ранее).

Рассмотрим ситуацию, когда структура данных стек не содержит ни одного элемента. В этом случае указатель на вершину стека top ссылается/указывает в NIL.

NIL - специальный зарезервированный участок памяти, служащий "бухтой" для динамических переменных-указателей. Чтобы указатели "не болтались" в памяти, их обычно "привязывают" к NIL. То есть, по сути, top является нулевым указателем.

Поскольку осуществляется добавление нового элемента, то необходимо динамически выделить память под добавляемый элемент. В языке программирования Pascal для распределения динамической памяти употребляют процедуру new.

В самом широком смысле выделение памяти и инициализация полей производится так:

  1. {выделение памяти под добавляемый элемент}
  2.     new(p);
  3. {"привязали" линковочное поле к NIL, чтобы не было висячей ссылки}
  4.     p^.link := NIL;
  5. {ввод значения информационного поля элемента с клавиатуры}
  6.     write('Введите значение добавляемого элемента: ');
  7.     readln(p^.inf);

то есть, видно, что сначала происходит выделение памяти под сам добавляемый элемент, а затем инициализация информационного поля соответствующим значением, а линковочное поле устанавливается в NIL.

Схема добавления первого элемента в вершину "нулевого" стека

Исходное состояние структуры данных стек, когда нет ни одного элемента. Об этом сигнализирует указатель top, который ссылается в NIL.

Другими словами, стек не содержит ни одного элемента.

Выделяем память под добавляемый элемент и ставим на него указательную переменную p.

Напомню, что в языке программирования Pascal для распределения динамической памяти используется процедура new.

Первой операцией производим установку ссылочного поля добавляемого элемента на то место в памяти, куда указывает указатель на вершину стека top.

Поскольку в стеке нет элементов, то ссылочное поле link добавляемого элемента начинает ссылаться на NIL.

Необходимо обратить внимание на то, что в данный момент top указывает не на вершину стека, а в NIL, но это лишь на мгновение, равное такту процессора.

Второй операцией производим перенос указателя, ссылающегося изначально на вершину стека, обозначенный на картинке справа как top, на только что добавленный элемент.

Указательная переменная top "уходит из бухты NIL" и начинает ссылаться на тот участок памяти, на который ссылается и переменная p.

То есть структура данных стек принимает окончательное согласованное состояние: указатель top ссылается на самый верхний элемент стека.

Вывод: операция добавления в вершину нулевого стека успешно проведена.

Схема добавления первого элемента в вершину стека, содержащего элементы

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

Как видно из схемы, стек содержит 3 элемента. Ссылочное поле нижнего элемента указывает в NIL. Указатель на вершину стека top ссылается на самый верхний элемент.

Выделяем память под добавляемый элемент и ставим на него указательную переменную p.

Напомню, что в языке программирования C++ для распределения динамической памяти используется функция new.

Первой операцией производим установку ссылочного поля добавляемого элемента на то место в памяти, куда указывает указатель на вершину стека top.

Поскольку в стеке три элемента, то ссылочное поле link добавляемого элемента начинает ссылаться на самый верхний/первый элемент.

Необходимо обратить внимание на то, что в данный момент указательная переменная top указывает не на вершину структуры данных стек, а уже на "второй" элемент, но это лишь на мгновение, равное такту процессора.

Второй операцией производим перенос указателя на вершину стека (обозначен на схеме как top) на только что добавленный элемент. То есть стек принимает окончательное согласованное состояние: указатель top ссылается на самый верхний элемент стека. В итоге в стеке становится 4-ре элемента.

Вывод: операция добавления в вершину не нулевого стека успешно проведена.

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

Схема удаления верхнего элемента из стека

Удаление элемента будет физически возможным, если в стеке имеется хотя бы один элемент. Если стек пуст, то есть является нулевым, то операцию удаления элемента невозможно произвести. Технология операции удаления из стека верхнего элемента не зависит от количества элементов в стеке.

Как видно из схемы, стек содержит ровно три элемента. Ссылочное поле нижнего элемента указывает в NIL. Указатель на вершину стека top ссылается на самый верхний элемент. То есть стек находится в согласованном состоянии.

Для реализации удаления элемента из стека потребуется вспомогательный указатель p.

Первым действием необходимо установить вспомогательный указатель p на удаляемый элемент, то есть установить на первый элемент стека, на который также ссылается и указатель top.

Вторым действием необходимо "перебросить" указатель на вершину стека top на второй элемент.

Кстати, второго элемента может и не быть физически, если изначально структура данных стек состояла только из единственного элемента.

В этом случае, top мигрирует в "бухту" NIL.

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

Поэтому уводим указатель удаляемого элемента линковочного поля в NIL. Кстати, не стоит опасаться того, что стек будет нарушен, так как на "второй" элемент установлен top, следовательно, связь между элементами не потеряна.

Производим удаление самого верхнего элемента из структуры данных стек. Напомню, что в языке программирования Pascal динамическая память высвобождается при помощи процедуры Dispose.

На данный момент операция удаления производится абсолютно безболезненно и не происходит абсолютно никаких нарушений в стеке, особенно на уровне взаимных связей между элементами.

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

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

Схема печати всех элементов стека

Печать элементов из структуры данных стек будет физически возможной, если в стеке имеется хотя бы один элемент. Если стек пустой/нулевой, то операцию визуализации элементов невозможно произвести.

Вообще, печать элементов структуры данных стек нельзя относить к фундаментальным операциям, а лишь к вспомогательным операциям.

Предположим, что начальный стек содержит три элемента. Для визуализации значения информационных полей элементов стека необходим дополнительный указатель. Введем идентификатор p.

Справа представлен полный процессинг всех итераций по печати элементов стека на экран пользователя.

Важно заметить следующее, что распечатка всех элементов на экран - итерационный процесс, следовательно, при программировании используют циклы, как правило, цикл с предусловием, то есть цикл while-do.

Как видно из представленной схемы, как только вспомогательный указатель p достигнет NIL, операция вывода будет официально завершена. После окончания печати всех элементов стека, сам стек остается в согласованном состоянии.

Удаление всех элементов стека

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

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

Рассмотрим пример очищения структуры данных стек, состоящего из трех элементов. Очевидно, что операция удаления всех элементов из стека равносильна операции удаления элемента из вершины стека, взятая несколько раз подряд. То есть, по сути, происходит циклическое удаление элемента из вершины стека до тех пор, пока структура данных стек не станет пустой, а точнее, когда указатель на вершину стека будет ссылаться в NIL.

На схеме, представленной выше, производится удаление элемента из вершины стека. Для корректной операции удаления элемента из вершины стека потребовался вспомогательный указатель р. В итоге в стеке остается два элемента.

 

На схеме, представленной выше, производится удаление элемента из вершины стека. Для корректной операции удаления элемента из вершины стека потребовался вспомогательный указатель р. В итоге в стеке остается один элемент. Это вторая итерация цикла, так как производится удаление уже второго узла стека.

 

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

Вывод: операция удаления всех элементов из стека успешно проведена.

Нестандартные операции для работы со стеком

  1. Расщепление структуры исходного стека на два различных подстека по какому-либо признаку.

  2. Слияние элементов из двух или более однородных стековых структур в консолидирующий стек по какому-либо признаку.

  3. Сортировка стека по заданному ключу.

  4. Поиск элемента стека по заданному критерию (в качестве критерия, как правило, выступает значение информационного поля элемента).

  5. Переворот элементов стека. Элемент, являющийся вершиной стека становится его последним (замыкающим) элементом, а последний (замыкающий) элемент становится первым, то есть превращается в ведущий элемент.

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

Печать элементов стека от замыкающего к начальному элементу, используя рекурсивный вызов

Как видно из представленной схемы рекурсивной печати элементов, для обхода стека требуется вспомогательный указатель (им является идентификатор pp).

На картинке справа показаны вложенные копии вызова рекурсивной процедуры, причем в каждой версии процедуры существует "свой" указатель pp, указывающий на соответствующий элемент стека.

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

Как видно из изображения, рекурсия закончилась, когда указатель pp достиг критического значения, то есть вышел в NIL. Как только это случилось, рекурсивные копии процедур начали закрываться, и именно в этот момент происходит визуализация значений информационных полей на дисплей пользователя.

Подобный вариант рекурсии имеет название рекурсия на возврате. В каждой копии процедуры имеется элемент, у которого подписано слово "значение", вот именно данное значение и будет распечатано на экране.

Реализация стека на языке программирования Pascal

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

Приведенная структура данных стек способна обрабатывать только целые числа. Как я ранее писал в данной статье, выбор типа данных не является критичным и легко может быть заменен на нужный тип данных.

Программа реализует следующие операции над стеком:

  • Добавление элемента в вершину стека.

  • Удаление элемента из вершины стека.

  • Печать элементов стека на дисплее пользователя (от вершины к концу).

  • Печать элементов стека на дисплее пользователя (рекурсивно).

  • Получение общего количества элементов в стеке.

  • Удаление всех элементов из стека.

Скачать программу реализации динамического СТЕКА на языке программирования Turbo Pascal 7.0.

Если вас интересует реализация дополнительного функционала по структуре данных стек, например, вы хотите познакомиться с какой-либо функцией или процедурой, не представленной в этой статье, то сообщите об этом мне, написав на электронный адрес administrator@videoege.ru.

  1. {заголовок программы}
  2. program STACK;
  3. {раздел подключения сторонних модулей}
  4. uses
  5. {подключаем модуль crt - console run time, чтобы можно было
  6.  использовать подпрограммы для работы с консолью}
  7.     crt;
  8. {раздел декларации собственных типов данных}
  9. type
  10. {указательный тип данных на элемент Стека}
  11.     Tptr = ^Telem;
  12. {запись, состоящая из двух полей, описывающая элемент Стека}
  13.     Telem = record
  14.         inf : integer;  {информационное поле - хранит целые числа}
  15.         link : Tptr;    {указательное поле - ссылка на следующий элемент Стека}
  16.     end;
  17. {раздел описания переменных}
  18. var
  19. {глобальная переменная - указатель на вершину Стека}
  20.     top : Tptr;
  21. {---------------------------------------------------------------------------}
  22. {Процедура: добавление элемента в вершину Стека}
  23. {---------------------------------------------------------------------------}
  24. procedure push;
  25. var
  26. {вспомогательный указатель, ссылающийся на добавляемый элемент}
  27.     p : Tptr;
  28. {начало тела процедуры}
  29. begin
  30. {выделение памяти под добавляемый элемент}
  31.     new(p);
  32. {"привязали" линковочное поле к NIL, чтобы не было висячей ссылки}
  33.     p^.link := NIL;
  34. {ввод значения информационного поля элемента с клавиатуры}
  35.     write('Введите значение добавляемого элемента: ');
  36.     readln(p^.inf);
  37. {указатель добавляемого элемента поставили на первый элемент Стека}
  38.     p^.link := top;
  39. {указатель на вершину Стека top поставили на только что добавленный элемент.
  40.  В итоге, Стек находится в согласованном состоянии после добавления элемента}
  41.     top := p;
  42. {конец тела процедуры}
  43. end;
  44. {---------------------------------------------------------------------------}
  45. {Процедура: удаление элемента из вершины Стека}
  46. {---------------------------------------------------------------------------}
  47. procedure pop;
  48. var
  49. {вспомогательный указатель, ссылающийся на удаляемый элемент}
  50.     p : Tptr;
  51. {начало тела процедуры}
  52. begin
  53. {позиционируем указатель p на вершину Стека}
  54.     p := top;
  55. {поскольку на первый элемент ссылается уже два указателя p и top,
  56.  следовательно, один из указателей можно "отвязать" от первого элемента.
  57.  Поэтому перемещаем top с верхнего элемента на второй элемент Стека}
  58.     top := p^.link;
  59. {окончательно разрушаем связь между первым и вторым элементом, так как
  60.  первый элемент сейчас будет удаляться}
  61.     p^.link := NIL;
  62. {удаляем первый элемент Стека}
  63.     dispose(p);
  64. {конец тела процедуры}
  65. end;
  66. {---------------------------------------------------------------------------}
  67. {Процедура: печать элементов Стека от вершины в конец}
  68. {---------------------------------------------------------------------------}
  69. procedure printFromTop;
  70. var
  71. {вспомогательный указатель, ссылающийся на текущий элемент Стека}
  72.     p : Tptr;
  73. {начало тела процедуры}
  74. begin
  75. {устанавливаем указатель р на первый элемент Стека}
  76.     p := top;
  77. {выпечатываем на экран диалог}
  78.     write('Элементы стека имеют вид: ');
  79. {до тех пор, пока указатель р не выйдет за последний элемент Стека}
  80.     while(p <> NIL) do
  81.     begin
  82. {печатаем на экран пользователя информационное поле текущего элемента Стека,
  83.  причем целые числа печатаются через пробел, чтобы вывод был понятным}
  84.         write(p^.inf, ' ');
  85. {переход на следующий элемент Стека}
  86.         p := p^.link;
  87.     end;
  88. {конец тела процедуры}
  89. end;
  90. {---------------------------------------------------------------------------}
  91. {Рекурсивная (возврат) процедура: печать элементов Стека от конца к вершине}
  92. {---------------------------------------------------------------------------}
  93. {процедура принимает параметр - указатель на вершину Стека}
  94. procedure printRecFromEnd(pp : Tptr);
  95. begin
  96. {любая рекурсия обязана иметь элементарный случай, чтобы завершится. В
  97.  данной процедуре, элементарным случаем является ситуация, когда
  98.  указатель вышел за последний элемент стека, то есть ссылается на NIL}
  99.     if(pp <> NIL) then
  100.     begin
  101. {рекурсивный вызов, в качестве параметра передается указатель на
  102.  следующий элемент Стека}
  103.         printRecFromEnd(pp^.link);
  104. {печать значения информационного поля текущего элемента
  105.  причем целые числа печатаются через пробел, чтобы вывод был понятным}
  106.         write(pp^.inf, ' ');
  107.     end;
  108. {конец тела процедуры}
  109. end;
  110. {---------------------------------------------------------------------------}
  111. {Процедура: удаление всех элементов из Стека}
  112. {---------------------------------------------------------------------------}
  113. procedure delAllStack;
  114. var
  115. {вспомогательный указатель}
  116.     p : Tptr;
  117. begin
  118. {удаление элементов начинается с первого элемента Стека}
  119.     p := top;
  120. {пока не будут удалены все элементы из Стека, то есть пока указатель р
  121.  не станет равным NIL начинаем цикл}
  122.     while(p <> NIL) do
  123.     begin
  124. {чтобы удалить текущий элемент и не потерять связь со следующим, переставляем
  125.  указатель top на следующий элемент Стека}
  126.         top := p^.link;
  127. {окончательно разрушаем связь между удаляемым и следующим элементом, так как
  128.  текущий элемент сейчас будет удаляться}
  129.         p^.link := NIL;
  130. {удаляем верхний элемент из Стека}
  131.         dispose(p);
  132. {установка указателя р снова на вершину Стека}
  133.         p := top;
  134.     end;
  135. {конец тела процедуры}
  136. {*примечание: указатель на вершину Стека top должен ссылаться на NIL}
  137. end;
  138. {---------------------------------------------------------------------------}
  139. {Функция: нахождение количества элементов в Стеке}
  140. {---------------------------------------------------------------------------}
  141. function getCountElem : integer;
  142. var
  143. {вспомогательный указатель}
  144.     p : Tptr;
  145. {хранит количество элементов в Стеке}
  146.     k : integer;
  147. {начало тела функции}
  148. begin
  149. {зануляем количество, так как расчет еще не начался}
  150.     k := 0;
  151. {указатель p стартует с самого верхнего элемента Стека}
  152.     p := top;
  153. {до тех пор пока р не выйдет за последний элемент, то есть в NIL
  154.  будем вести подсчет элементов}
  155.     while(p <> NIL) do
  156.     begin
  157. {счетчик, отвечающий за количество элементов увеличиваем на единицу}
  158.         k := k + 1;
  159. {переходим на следующий элемент Стека}
  160.         p := p^.link;
  161.     end;
  162. {в качестве ответа возвращаем количество элементов в Стеке}
  163.     getCountElem := k;
  164. end;
  165. {---------------------------------------------------------------------------}
  166. {Функция: главное меню программы}
  167. {---------------------------------------------------------------------------}
  168. function menu : integer;
  169. var
  170. {хранит значение пункта меню выбранного пользователем}
  171.     sel : integer;
  172. {начало тела функции}
  173. begin
  174. {запускаем визуализацию пунктов меню в цикле, до тех пор пока, пользователь
  175.  не выберет какой-либо заданный пункт меню}
  176.     repeat
  177.         clrscr;
  178.         writeln('1 - ДОБАВИТЬ ЭЛЕМЕНТ В ВЕРШИНУ СТЕКА');
  179.         writeln('2 - УДАЛИТЬ ЭЛЕМЕНТ ИЗ ВЕРШИНЫ СТЕКА');
  180.         writeln('3 - ПЕЧАТЬ ЭЛЕМЕНТОВ СТЕКА НА ЭКРАНЕ ОТ ВЕРШИНЫ ВНИЗ');
  181.         writeln('4 - РЕКУРСИВНАЯ ПЕЧАТЬ СТЕКА НА ЭКРАНЕ ОТ НИЗА К ВЕРШИНЕ');
  182.         writeln('5 - ПОЛУЧИТЬ ОБЩЕЕ КОЛИЧЕСТВО ЭЛЕМЕНТОВ В СТЕКЕ');
  183.         writeln('6 - УДАЛЕНИЕ ВСЕХ ЭЛЕМЕНТОВ ИЗ СТЕКА');
  184.         writeln('7 - ВЫХОД');
  185.         writeln;
  186.         write('Выберите один из предложенных пунктов: ');
  187. {возможна ошибка ввода, если пользователь введет, например, не число, а
  188.  какой-нибудь символ или даже строковое значение. Обработки ошибок нет!}
  189. {считываем с клавиатуры пункт меню, выбранный пользователем}
  190.         readln(sel);
  191. {стоит небольшая защита на диапазон от 1 до 7}
  192.     until((sel >= 1) and (sel <= 7));
  193.     writeln;
  194. {в качестве ответа возвращается число, указанное пользователем}
  195.     menu := sel;
  196. {конец тела функции}
  197. end;
  198. {---------------------------------------------------------------------------}
  199. {Начало основного блока программы}
  200. {---------------------------------------------------------------------------}
  201. var
  202. {хранит выбор пользователя относительно главного меню}
  203.     sel : integer;
  204. begin
  205. {очистка экрана от прошлых выводов и установка цвета текста белым}
  206.     clrscr;
  207.     textColor(WHITE);
  208. {изначально Стек путь, то есть не содержит элементов}
  209.     top := NIL;
  210. {пока пользователь не выберет пункт меню, отвечающий за выход из программы,
  211.  будет появляться интерактивное меню}
  212.     repeat
  213. {получаем номер операции от пользователя и затем начинаем анализировать
  214.  номер и вызываем соответствующую подпрограмму}
  215.         sel := menu;
  216.         case sel of
  217.             1:
  218.             begin
  219. {вставка элемента в вершину Стека}
  220.                 push;
  221. {оповещение пользователя об успешном завершении операции}
  222.                 writeln;
  223.                 write('Добавление нового элемента успешно проведено!');
  224.                 readln;
  225.             end;
  226.             2:
  227.             begin
  228. {если в Стеке нет ни одного элемента, то удаление физически невозможно}
  229.                 if(top = NIL) then
  230.                     writeln('В стеке нет элементов для удаления!')
  231.                 else
  232.                 begin
  233. {удаление элемента из вершины Стека}
  234.                     pop;
  235. {оповещение пользователя об успешном завершении операции}
  236.                     writeln;
  237.                     write('Удаление элемента из вершины Стека успешно проведено!');
  238.                 end;
  239.                 readln;
  240.             end;
  241.             3:
  242.             begin
  243. {если в Стеке нет элементов, то вызываем диалог для пользователя}
  244.                 if(top = NIL) then
  245.                     write('Печать элементов невозможна, так как Стек пуст!')
  246.                 else
  247. {печать элементов Стека от вершины вниз}
  248.                     printFromTop;
  249.                 readln;
  250.             end;
  251.             4:
  252.             begin
  253. {если в Стеке нет элементов, то вызываем диалог для пользователя}
  254.                 if(top = NIL) then
  255.                     write('Печать элементов невозможна, так как Стек пуст!')
  256.                 else
  257.                 begin
  258.                     write('Элементы стека имеют вид: ');
  259. {рекурсивная печать элементов Стека от конца к вершине}
  260.                     printRecFromEnd(top);
  261.                 end;
  262.                 readln;
  263.             end;
  264.             5:
  265.             begin
  266. {определяем количество элементов в Стеке}
  267.                 write('Количество элементов Стека: ', getCountElem);
  268.                 readln;
  269.             end;
  270.             6:
  271.             begin
  272. {удаление всех элементов из Стека}
  273.                 delAllStack;
  274.                 write('Все элементы Стека успешно удалены!');
  275.                 readln;
  276.             end;
  277.         end;
  278.     until(sel = 7);
  279. {перед тем, как закрыть программу, обязательно надо вызывать процедуру,
  280.  отвечающую за удаление всех элементов Стека, чтобы не было утечки памяти}
  281.     delAllStack;
  282. {конец главного блока программы}
  283. end.

РЕПЕТИТОР
ПО ИНФОРМАТИКЕ
И ПРОГРАММИРОВАНИЮ

ЧИТАТЬ
ОТЗЫВЫ МОИХ
УЧЕНИКОВ

Смотреть отзывы

АДРЕС
ЭЛЕКТРОННОЙ ПОЧТЫ
РЕПЕТИТОРА

Написать письмо

ЗАКАЗАТЬ
РАБОТУ ПО
ПРОГРАММИРОВАНИЮ

Работа на заказ

 

 
 
 
 
Авторизация на сайте
 
 
 
Обнаружили
ошибку на сайте?
Занятия по информатике