- •64 Жегуло а.И. Компьютерные науки 2-й семестр 2011-2012 гг. Компьютерные науки Лекции для студентов 1 курса мехмата, 2011-2012 уч. Г.
- •2 Семестр
- •16.Модули
- •16.1.Модуль и модульное программирование
- •16.2.Структура модуля
- •Interface //Раздел интерфейса
- •Implementation //Раздел реализации
- •Initialization //Раздел инициализации
- •Пример модуля и его использования
- •Interface //Раздел интерфейса
- •Implementation //Раздел реализации
- •Заголовок модуля
- •Раздел интерфейса interface
- •Раздел реализации implementation
- •Раздел инициализации initialization
- •16.4.Использование объявленных в модуле объектов
- •17.Файлы
- •17.1.Файлы. Классификация файлов
- •17.2.Организация работы с файлами
- •17.3.Подпрограммы для работы с файлами любых типов Связывание файловой переменной с файлом
- •Запись в файл
- •17.5.Обработка ошибок ввода-вывода
- •17.6.Текстовые файлы
- •17.6.1.Структура текстового файла
- •17.6.2.Особенности открытия текстовых файлов
- •17.6.3.Особенности чтения и записи для текстовых файлов
- •17.6.7.Поэлементная обработка текстовых файлов, состоящих из строковых значений и чисел
- •17.7.Типизированные файлы
- •17.7.1.Описание и структура типизированного файла
- •17.7.5.Сравнение текстовых и типизированных файлов
- •17.7.6.Пример работы с типизированными файлами из записей
- •18.Процедурные типы
- •18.1.Назначение процедурных типов
- •18.2.Описание процедурных типов и процедурных переменных
- •18.3.Присваивание процедурным переменным. Вызов подпрограмм через процедурные переменные
- •18.4.Процедурные переменные в качестве параметров
- •19.Рекурсия
- •19.1.Что такое рекурсия
- •19.2.Рекурсивные подпрограммы
- •19.3.Прямая и косвенная рекурсия
- •19.4.Предварительное (опережающее) описание подпрограммы
- •19.5.Опасности рекурсии
- •19.5.1.Бесконечная рекурсия
- •19.5.2.Глубокая рекурсия
- •19.5.3.Итерация и рекурсия, необоснованное применение рекурсии
- •19.6.Когда использовать рекурсию
- •19.7.Формы рекурсивных подпрограмм
- •19.8.Примеры рекурсивных программ
- •19.8.1.Вывод цифр целого числа в прямом порядке
- •19.8.2.Поиск максимального элемента массива
- •19.9.Задача о Ханойских башнях
- •20.Указатели
- •20.1.Указательные типы
- •Описание типизированного указателя
- •20.2.Операции с указателями
- •20.3.Примеры присваивания для указателей
- •20.4.Статические и динамические переменные
- •Создание новой динамической переменной базового типа и установка на нее указателя
- •Уничтожение динамической переменной, на которую ссылается указатель
- •Проблема потерянных ссылок
- •21.Динамические структуры данных
- •21.1.Данные статической структуры и данные динамической структуры
- •21.2.Односвязные линейные списки
- •21.2.1.Структура односвязного линейного списка
- •Вставка элемента после заданного элемента
- •21.3.Стеки
- •21.3.1.Реализация стека через односвязный линейный список
- •21.3.2.Применение стеков
- •21.3.3.Реализация стека на основе массива
- •21.4.Деревья
- •21.4.1.Основные определения
- •Алгоритм построения идеально сбалансированного дерева
- •21.4.3.Способы обхода дерева
- •Деревья поиска
- •Построение дерева поиска
21.3.Стеки
С тек – динамическая структура данных, представляющая из себя упорядоченный набор элементов, в которой добавление новых элементов и удаление существующих производится с одного конца, называемого вершиной стека.
По определению, элементы извлекаются из стека в порядке, обратном их добавлению, т.е. действует принцип «последним пришёл – первым вышёл» (LIFO – Last In First Out).
Основные операции над стеком:
Занесение в стек (принято называть Push);
Выборка из стека (принято называть Pop);
Дополнительные операции:
Создание пустого стека (DoTop);
Проверка, пуст ли стек (IsEmpty);
Просмотр элемента в вершине стека без удаления (InTop);
Перемена местами двух элементов в вершине стека (Swap).
21.3.1.Реализация стека через односвязный линейный список
Стек можно рассматривать как частный случай односвязного линейного списка, для которого разрешено добавлять и удалять элементы только с одного конца, а именно с головы. Каждый элемент стека хранится в записи с двумя полями: inf, содержащего сам элемент, и next, содержащего указатель на запись со следующим элементом.
Указатель Top ссылается на запись, находящуюся в вершине стека.
type ref=^Elem; {Тип указателя на элементы стека}
Elem = record {Тип элемента стека}
inf:integer; {Поле для информации}
next:ref {Поле для указателя на следующий элемент}
end;
var Top:ref;
procedure DoTop; //Создание пустого стека}
begin
Top:=nil
end;
function IsEmpty:boolean; //Проверка, пуст ли стек
begin
Result:=(Top=nil)
end;
procedure Push(x:integer); //Занесение числа x в стек
var p:ref;
begin
new(p);
p^.inf:=x;
p^.next:=Top; {Новый элемент стека указывает на прежнюю вершину стека}
Top:=p {Указатель вершины стека установлен на новый элемент стека}
end;
function Pop:integer; //Выборка из стека целого числа
var p:ref;
begin
Result:=Top^.inf; //Значение из вершины стека
p:=Top;
Top:=Top^.next; //Исключение верхнего элемента
dispose(p) //Освобождение динамической памяти, которую занимал элемент из вершины стека
end;
function InTop:integer; //Просмотр элемента в вершине стека без удаления}
begin
Result:=Top^.inf; //Значение из вершины стека
end;
procedure Swap; //Перемена местами двух элементов в вершине стека
var x:integer;
begin
x:=Top^.inf;
Top^.inf:=Top^.next^.inf;
Top^.next^.inf:=x;
end;
21.3.2.Применение стеков
Стеки используют при синтаксическом анализе текста в компиляторах, при вычислении выражений. Через стек реализован вызов подпрограмм: подпрограмма, вызванная последней, первой заканчивает работу.
Пример. Пусть имеется текстовая строка, сбалансированная по круглым скобкам. Необходимо вывести таблицу, в каждой строке которой будут находиться координаты соответствующих пар скобок, т.е. номера символов ‘(‘ и ‘)’ в строке.
Будем посимвольно просматривать строку и как только встретим открывающую скобку ‘(‘, занесем ее координату в стек. При встрече закрывающей скобки ‘)’ возьмем из стека верхний элемент (это координата открывающей скобки) и выведем ее в таблицу вместе с координатой данной ‘)’. Если при попытке взятия из стека он окажется пустым, а после завершения просмотра строки, наоборот, не пустым, число открывающих и закрывающих скобок не совпадает.
Допустим, имеем строку
( |
a |
+ |
b |
* |
c |
) |
/ |
2 |
- |
( |
a |
+ |
b |
) |
* |
( |
d |
+ |
c |
/ |
( |
f |
- |
g |
) |
) |
1 |
|
|
|
|
|
7 |
|
|
|
11 |
|
|
|
15 |
|
17 |
|
|
|
|
22 |
|
|
|
26 |
27 |
Должна быть получена таблица:
Откр Закр
1 7
11 15
22 26
17 27
procedure Error;
begin writeln(‘Число открывающих и закрывающих скобок не совпадает’); halt {Прекращение работы программы}
end;
begin {программа}
DoEmpty; {Создание пустого стека}
write(‘Введите строку’); readln(S);
for i:=1 to length(S) do
begin
if S[i]=‘(‘ then Push(i); {Занесение в стек номера символа ‘(‘}
if S[i]=‘)‘
then if not IsEmpty {Стек не пуст при встрече ‘)’}
then writeln(Pop:4,i:4) {Вывод координаты ‘(‘ из стека и координаты ‘)’}
else Error
end;
if not IsEmpty then Error {Если стек не пуст после завершения просмотра строки}
end.