Алгоритм освобождения памяти, занятой стеком

1. Начинаем цикл, выполняющийся пока begin не станет равным NULL.

2. Устанавливаем текущий указатель на вершину стека: t = begin;

3. Вершину стека переставляем на следующий элемент: begin = t->Next;

4. Уничтожаем текущий (бывшую вершину) элемент, т.е. освобождаем занятую под него память free(t);

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

void Delete_Stack(Stack **begin) {

Stack *t;

while( *begin != NULL) {

t = *begin;

*begin = (*begin) -> Next;

free(t);

}

}

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

Delete_Stack(&begin);

if(begin == NULL)

puts(“ Free! ”);

. . .

Алгоритм проверки правильности расстановки скобок

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

При реализации алгоритма анализа исходное выражение просматривается слева направо.

1. Если в выражении обнаружена открывающаяся скобка, то анализируем содержимое стека:

а) если стек пуст или не пуст, но в вершине находится тоже открывающая скобка, то записываем ее в стек;

б) если стек не пуст и в вершине находится закрывающая скобка, то обе скобки выбрасываем из рассмотрения (находящуюся в стеке удаляем).

2. Если обнаружена закрывающая скобка и стек пуст, то выражение составлено неверно, выводим сообщение об этом и завершаем работу.

3. Просмотрев все выражение, проверяем стек и, если он не пуст, то баланс скобок нарушен и выражение составлено неверно, выводим сообщение об этом и завершаем работу.

По такому принципу работают все компиляторы, проверяя баланс круглых скобок в выражениях, баланс фигурных скобок во вложенных блоках, вложенные циклы и т.п.

 

Структура данных ОЧЕРЕДЬ

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

Очередь также называют структурой данных, организованной по принципу FIFO (First In, First Out) – первый вошел (первый созданный элемент очереди), первый вышел.

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

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

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

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

Шаблон элемента структуры, информационной частью которого является целое число, может иметь следующий вид:

struct Spis {

int info;

Spis *Next;

};

При организации очереди обычно используют два указателя

Spis *begin, *end;

где begin и end – указатели на начало и конец очереди соответственно, т.е. при создании очереди мы организуем структуру данных следующего вида:

каждый элемент которой имеет информационную infо и адресную Next (A1, A2, ...) части.

Основные операции с очередью следующие:

– формирование очереди;

– добавление нового элемента в конец очереди;

– удаление элемента из начала очереди.

Формирование очереди

Формирование очереди состоит из двух этапов: создание первого элемента, добавление нового элемента в конец очереди.

Создание первого элемента очереди

Этот этап заключается в создании первого элемента, для которого адресная часть должна быть нулевой (NULL). Для этого нужно:

1) ввести информацию для первого элемента (целое число i);

2) захватить память, используя текущий указатель:

t = (Spis*) malloc(sizeof(Spis)); или t = new Spis;

в результате формируется конкретный адрес (А1) для первого элемента;

3) сформировать информационную часть:

t -> info = i; (обозначим i1 )

4) в адресную часть занести NULL:

t -> Next = NULL;

5) указателям на начало и конец очереди присвоить значение t:

begin = end = t;

На этом этапе получим следующее: