- •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.Способы обхода дерева
- •Деревья поиска
- •Построение дерева поиска
Алгоритм построения идеально сбалансированного дерева
Идея алгоритма: Построим и выведем на экран бинарное дерево минимальной глубины из n узлов, вычислим его глубину. Значениями узлов будут целые числа, вводимые с клавиатуры. Для получения минимальной глубины при заданном числе узлов надо располагать максимально возможное число узлов на всех уровнях, кроме самого последнего. Это достигается распределением всех поступающих узлов поровну слева и справа от каждого узла. Реализует эту идею рекурсивный алгоритм:
Взять один узел в качестве корня;
Построить левое поддерево с количеством узлов nL = n div 2 тем же способом;
Построить правое поддерево с количеством узлов nR = n-nL-1 тем же способом.
В программе этот алгоритм реализован рекурсивной функцией Tree.
program BinTree; {Построение идеально сбалансированного дерева, вывод его на экран, вычисление глубины дерева}
type ref = ^Node;
Node= record
Inf: integer;
Left,Right: ref
end;
var Root: ref; {Указатель на корень дерева}
H: integer; {Высота дерева}
n: integer; {Количество узлов}
function Tree(n: integer):ref; {Рекурсивная функция построения дерева из n узлов}
var t: ref; x,nL,nR: integer;
begin
If (n=0) then Tree:=nil
else begin
nL:=n div 2; {Половина узлов – в левом поддереве}
nR:=n-nL-1; {Половина узлов минус корень – в правом поддереве}
read(x);
new(t); {Выделение динамической памяти для узла}
t^.Inf:= x; {Итак, на рекурсивном спуске }
t^.Left :=Tree(nL); {Построение левого поддерева}
t^.Right:=Tree(nR); {Построение правого поддерева}
Tree:= t
end
end; { конец функции Tree }
procedure PrintTree (t: ref; h: integer); {Вывод дерева. Обход дерева справа налево.
t – указатель на поддерево; h – уровень узла поддерева, используется для отступа от левого края экрана}
const blank=' '; {пробелы для отступа каждого уровня}
var i : integer;
begin
if (t<>nil) then begin
PrintTree (t^.Right, h+1);
for i:=1 to h do write(blank); {Отступ на уровень h}
writeln(t^.Inf);
PrintTree (t^.Left, h+1) end
end;
function Height(t:ref):integer; {Определение высоты дерева. Обход дерева снизу вверх}
var hL, hR: integer;
begin
if (t=nil) then Height:= -1 {Если дерево пустое, функция выдает значение –1}
else begin
hL:=Height(t^.Left); {Определение высоты левого поддерева}
hR:=Height(t^.Right); {Определение высоты правого поддерева}
if (hL>hR) then Height:=hL + 1
else Height:=hR + 1
end
end; { конец функции Height}
begin {основная программа}
write('n='); readln(n);
Root:= Tree(n);
PrintTree(Root, 0); {Корень дерева печатается на уровне 0, без отступа от края экрана}
H:=Height(Root); writeln('Высота H=', H)
end.
Если ввести n=7 и значения узлов 1, 2, 3, 4, 5, 6, 7, то получим на экране изображение дерева:
|
7 5 6 1 4 2 3 |
Уровень узла: h=2 h=1 h=2 h=0 h=2 h=1 h=2 |
|
Высота H=2 |
|