- •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.Способы обхода дерева
- •Деревья поиска
- •Построение дерева поиска
Деревья поиска
Двоичные деревья часто используются для представления наборов данных, элементы которого ищутся по уникальному, только им присущему ключу.
Деревом поиска называется такое бинарное дерево, в котором для ключа каждого узла все ключи его левого поддерева меньше ключа узла, а все ключи его правого поддерева больше ключа узла.
Деревья поиска можно использовать для сортировки. Например, для сортировки массива надо построить дерево поиска по значениям элементов массива, а затем обойти дерево слева направо (синтаксический обход), записывая значения узлов дерева в результирующий массив. Скорость поиска в деревьях поиска примерно такая же, что и в отсортированных массивах: O(Clog2n), в худшем случае O(n). |
|
Построение дерева поиска
При построении дерева поиска и при последующем поиске узла по его ключу место каждого ключа можно найти, двигаясь, начиная от корня, и переходя на левое или правое поддерево каждого узла в зависимости от значения ключа.
Начиная с пустого дерева, очередное число ищется в дереве:
Если число найдено, увеличивается его счетчик появления.
Если нет, число вставляется в дерево с начальным значением счетчика=1.
Поскольку определение двоичного дерева рекурсивно, то все операции над деревом могут быть реализованы в виде рекурсивных подпрограмм. Замечание: использование рекурсии замедляет работу программы и расходует лишнюю память при её выполнении.
program TreeSearch; {Дерево поиска}
type ref=^node;
node=record
key:integer;
count:integer;
left,right:ref
end;
var Root:ref; k:integer;
procedure Gen(x:integer; var t:ref); {Генерация нового узла}
begin
new(t);
t^.key:=x; t^.count:=1;
t^.left:=nil; t^.right:=nil
end;
procedure Search (x:integer; var t:ref);{Поиск х в дереве t}
begin
if t=nil
then Gen(x,t) {Добавление узла в дерево, т.к. числа x в дереве нет}
else if (x = t^.key)
then t^.count:=t^.count+1 {Число x есть в дереве}
else if (x < t^.key)
then Search(x, t^.left) {Поиск в левом поддереве}
else Search(x, t^.right) {Поиск в правом поддереве}
end;
procedure PrintTree(t:ref; h:integer); {Вывод дерева. Обход дерева справа налево}
var i:integer;
begin
if t<>nil then
begin
PrintTree(t^.right,h+1);
for i:=1 to h do write(' ');
writeln(t^.key, ’_', t^.count);
PrintTree(t^.left, h+1);
end
end;
procedure Infix(t: ref); {Обход дерева слева направо. Дает вывод в отсортированном порядке}
begin
if (t<>nil)
then begin
Infix(t^.Left); {Переход в левое поддерево}
write(t^.key:3);
Infix(t^.Right) {Переход в правое поддерево}
end
end;
begin
Root:=nil; {Создание пустого дерева}
write('='); readln(k);
while (k<>0) do {При k=0 построение дерева завершается}
begin
Search(k, Root);
write('='); readln(k);
end;
PrintTree(Root,0);{Вывод дерева}
Infix(Root); {Вывод листьев дерева в отсортированном порядке}
end.