- •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.Способы обхода дерева
- •Деревья поиска
- •Построение дерева поиска
Вставка элемента после заданного элемента
Исходный список |
Список после вставки элемента |
|
|
Выполнить проход (a) по списку с проверкой текущего элемента для поиска заданного элемента А.
Если элемент найден, выполнить:
new(q);
q^.inf:=x;
q^.next:=p^.next; //Установка ссылки в новом элементе на элемент, который следовал за элементом А
p^.next:=q; //Установка ссылки в элементе А на новый элемент
end;
Вставка элемента перед заданным (но не первым) элементом A
Исходный список |
|
Вставить элемент после заданного (см. выше), затем поменять местами значения полей inf заданного и нового элементов.
Удаление заданного (но не первого) элемента
Исходный список |
Список после удаления элемента |
|
|
Выполнить проход (c) по списку с двумя указателями в поисках заданного элемента А.
Если элемент найден, выполнить:
pred^.next:=p^.next;//Изменение поля ссылки в предшествующем элементе для обхода удаляемого
Dispose(p); //Освобождение памяти, которую занимал удаляемый элемент
p:=nil
Вставка элемента в конец списка
Исходный список |
Список после вставки |
|
|
Выполнить проход (b) по списку с проверкой наличия элемента, следующего за текущим, затем:
new(q);
q^.inf:=x;
q^.next:=nil;//Новый элемент никуда не ссылается
p^.next:=q; //Установка ссылки бывшего последнего элемента на новый элемент
Вставка элемента перед последним
Исходный список |
Список после вставки |
|
|
Вставить элемент в конец списка (см. выше), затем поменять местами значения полей inf последнего и нового элементов.
Удаление последнего элемента
Исходный список |
Список после удаления |
|
|
Выполнить проход (d) по списку с двумя указателями и с проверкой
наличия элемента, следующего за текущим, затем:
pred^.next:=nil;{Предпоследний элемент становится последним}
Dispose(p); {Освобождение памяти, которую занимал последний элемент}
p:=nil;
21.2.3.Операции над каждым элементом односвязного линейного списка
Cумма элементов списка
p :=Head;
Sum:=0;
while p<>nil do
begin
Sum:=Sum+p^.inf;
p:=p^.next
end;
Поиск максимального элемента списка
p :=Head;
pmax:=p; //Первый элемент полагаем максимальным
while p<>nil do
begin
if (p^.inf > pmax^.inf) then pmax:=p;
p := p^.next
end; //На выходе указатель pmax ссылается на элемент с максимальной информационной частью
Вывод элементов списка в прямом порядке
procedure PrintList(p: ref);{Параметр p указывает на начало списка}
const str=' -> '; //Стрелка для отделения элементов списка при выводе
begin
while (p <> Nil) do
begin
write(str, p^.inf); //Вывод поля inf текущего элемента
p := p^.next
end;
writeln
end;
Вывод списка на экран в строку в обратном порядке рекурсивно
procedure RevPrintList(p:ref);{Параметр p указывает на начало списка}
const str=' <- '; //Стрелка для отделения элементов списка при выводе
begin
if (p <> nil) then
begin
RevPrintList(p^.next);
write(p^.inf, str) //Вывод поля inf текущего элемента на рекурсивном возврате
end;
21.2.4.Пример.
Создать односвязный линейный список с включением новых элементов в начало списка, вывести элементы списка в прямом и в обратном порядке
function NewElem(p: ref; x: integer): ref; {Создание нового элемента.
Параметр p указывает на начало списка}
var q: ref;
begin
new(q); {Выделение в динамической памяти места для нового элемента}
q^.inf:=x; {Заполнение поля данных}
q^.next:=p; {Заполнение поля ссылки}
Result:=q; {Результат функции – ссылка на новый элемент}
end;
begin
Head:= nil; {Создание пустого списка}
repeat
write('Элемент='); readln(x); {Ввод очередного числа}
if (x<>0) then
Head:=NewElem(Head, x);{Создание элемента и присоединение к голове списка}
until (x=0);
PrintList(Head); {Вывод списка от начала к концу}
RevPrintList(Head); {Рекурсивный вывод списка от конца к началу}
writeln;
end.