Пример: стек
Стек – одна из наиболее полезных структур данных. Стек позволяет вставлять и удалять данные, причем выполнение этих операций осуществляется исключительно над вершиной стека (то есть над самым верхним его элементом). Такой порядок называется «первым вошел, последним вышел» (last-in-first-out, LIFO). По идее, стек
ведет себя как стопка подносов: поднос оказывается наверху, если предыдущий забрали, или «опускается» в стопке вниз, если сверху положили еще один. Структура данных, основное назначение которой — хранение информации, называется контейнером (container).
Стек допускает следующие операции: push, pop, top, empty и full (поместить, извлечь, вершина, пусто, заполнен). Операция push помещает значение в стек, pop извлекает значение из стека и удаляет его, top возвращает верхнее значение в стеке, empty проверяет, не пуст ли стек, а full проверяет, не полон ли он. Стек является типичным АТД.
Реализуем стек как тип данных C++ для хранения символьных значений, используя структуру так, как она понимается в базовом языке. Реализация будет использовать символьный массив фиксированной длины для хранения содержимого стека. Вершиной стека будет член с именем top, принимающий целые значения. Различные операции со стеком будут реализованы в виде функций, список аргументов каждой из которых включает в качестве параметра указатель на ch_stack. Это позволит изменять стек и избежать его копирования при вызове по значению.
В файле ch_stacl.H
//Простая реализация типа ch_stack
const int max_len = 1000;
enuro { EMPTY = -1, FULL = max_len - 1 };
struct ch_stack {
char s[max_len];
int top;
};
Объявление struct создает новый тип – ch_stack. В нем два члена: член-массив s и целый член top.
// Стандартный набор операций с ch_stack
void reset(ch_stack* stk) //обнуление стека
{
stk -> top = EMPTY;
}
Эта функция используется для инициализации. Члену top присваивается значение EMPTY. Адрес
void push(ch_stack* stk, char c)
{
stk -> s[++stk -> top] = с; //приоритет: ++(stk -> top)
}
char pop(ch_stack* stk)
{
return (stk -> s[stk -> top--]);
}
Операция помещения в стек (push) реализована как функция двух аргументов. Член top увеличивается на единицу. Значение с помещается в вершину ch_stack. Эта функция полагает, что ch_stack не заполнен. Операция извлечения из стека (pop) реализована таким же образом; в ней предполагается, что ch_stack не пуст. Возвращается значение вершины стека, и член top уменьшается на единицу.
char top(ch_stack* stk)
{
return (stk -> s[stk -> top]) ;
}
bool empty(const ch_stack* stk)
{
return (stk -> top == EMPTY) ;
}
bool full(const ch_stack* stk)
{
return (stk -> top = = FULL);
}
Эти функции возвращают значение типа boo 1. Каждая из них проверяет член top на соответствующее условие. Например, перед вызовом push( ) программист проверить, что ch_stack не полон, для того чтобы функция push ( ) работала корректно. Эти функции не изменяют ch_stack, на который они направлены. Поэтому мы можем объявить аргументы-указатели как const. Во всех функциях аргумент ch_stack передается как адрес, а для доступа к членам используется оператор указателя структуры ->.
При условии, что описанные выше объявления находятся в файле ch_stac1.h, можно проверить операции со стеком с помощью следующей программы, которая помещает символы строки в стек и извлекает их, печатая символы в обратном порядке:
//Проверим ch_stack с помощью обращения строки
#include "ch_stacl.h"
#include <iostream.h>
int main()
{
ch_stack s;
char str[40] = {"Книгу перевел Денис Ковальчук!"};
int i = 0;
cout << str << endl; //печать строки
reset(&s) ;
while <str[i] && !full(&s)) //помещение в стек
push(&s, str[i++]);
while ("empty(&s)) //печать обращенной строки
cout << pop(&s) ;
cout << endl;
}
Вывод этой тестовой программы выглядит так:
Книгу перевел Денис Ковальчук!
!кучьлавоК синеД левереп угинК