- •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.Способы обхода дерева
- •Деревья поиска
- •Построение дерева поиска
19.8.Примеры рекурсивных программ
19.8.1.Вывод цифр целого числа в прямом порядке
procedure Print(x: integer);
begin
if x > 9 then Print(x div 10); //Рекурсивный вызов для числа x без младшей цифры
write(x mod 10 :3) //Вывод младшей цифры на рекурсивном возврате
end;
Цифры легче получать с конца числа. Поэтому на рекурсивном спуске мы путем деления на 10 получаем последовательность чисел, которые заканчиваются очередной цифрой с конца числа. На рекурсивном возврате мы эту младшую цифру получим как остаток от деления на 10 и выведем.
Пусть x=1234, тогда на рекурсивном спуске будут происходить следующие вызовы процедуры Print:
Print(1234); Print(123); Print(12); Print(1);
Рекурсивный спуск закончился, последний экземпляр Print выведет цифру 1.
На рекурсивном возврате Print(12) выведет цифру 2, Print(123) – цифру 3, Print(1234)‑ цифру 4.
В результате получим последовательность цифр: 1 2 3 4
19.8.2.Поиск максимального элемента массива
Суть рекурсивного поиска максимума в том, длина части массива, на которой ведется поиск, на каждом шаге рекурсивного спуска уменьшается на 1. Когда эта длина станет равной 1, принимаем за максимальный этот единственный рассматриваемый на данном шаге рекурсии элемент.
Больше рекурсивных вызовов не происходит, начинается завершение работы вызванных функций, т.е. рекурсивный возврат. На каждом шаге рекурсивного возврата к уже обработанной части массива добавляется один элемент. Если этот элемент A[L] больше найденного ранее максимума, то значение A[L] принимается за новое значение максимума.
const N=10;
type vector=array[1..N] of integer;
var V:vector; max:integer;
function RMax(const A:vector; L:integer):integer;
{ L – длина части массива, рассматриваемой на каждом шаге рекурсии.}
var M: integer;
begin
if L=1 then RMax:=A[1] //Считаем A[1] максимальным; рекурсивный спуск закончен
else begin
M:=RMax(A, L-1); //Уменьшение длины части массива на 1 на рекурсивном спуске
if A[L]>M then RMax:=A[L] //Сравнение на рекурсивном возврате
end
end;
begin ... max:=RMax(V, N); ...
end.
19.8.3.Быстрая сортировка – усовершенствованный метод сортировки обменом
Алгоритм быстрой сортировки, который разработал англичанин Чарльз Хоор (C. Hoare) в 1960 г., является наиболее популярным алгоритмом сортировки.
Анализ эффективности быстрой сортировки
В среднем число операций порядка Nlog2N, остальные сортировки в среднем N2 операций.
Преимущество быстрой сортировки проявляется при больших N. Она сортирует массив с элементами в обратном порядке практически с такой же скоростью, как уже отсортированный массив.
Принцип быстрой сортировки
Причина неэффективности метода сортировки обменом (метод «пузырька») в том, что меняются местами два соседних элемента, если для них нарушена упорядоченность. Менять местами надо максимально удаленные элементы.
Алгоритм одного шага быстрой сортировки
Просматривая массив слева направо, найти элемент Ai>x. Просматривая массив справа налево, найти элемент Aj<x. Если i<=j, то поменять местами Ai и Aj, увеличить i+1, уменьшить j-1 |
Пример одного шага быстрой сортировки |
Для сортировки массива надо то же самое проделать с обеими частями (слева и справа от x), затем с частями этих частей и т.д. до тех пор, пока каждая часть не будет содержать только один элемент. Получили рекурсивный алгоритм.
procedure QSort(L,R:integer); //L, R – индексы самого левого и самого правого элементов подмассива
var i,j,x,w:integer;
begin
i:=L; j:=R;
x:=A[(L+R) div 2]; //x - средний элемент
repeat
while A[i]<x do i:=i+1; //Просмотр слева направо
while A[j]<x do j:=j-1; //Просмотр справа налево
if i<=j then
begin //Перестановка A[i] и A[j]
w:=A[i];
A[i]:=A[j];
A[j]:=w;
i:=i+1; j:=j-1
end
until i>j;
if L<j then QSort(L,j); //Рекурсивный вызов для левой половины массива
if i < R then QSort(i,R) //Рекурсивный вызов для правой половины массива
end;
begin… Sort(1,N); . . .
end.