- •СТРУКТУРЫ ДАННЫХ И АЛГОРИТМЫ
- •Глава 1 Линейные списки
- •Понятие структуры данных
- •Тип указатель
- •Линейный список
- •Линейный однонаправленный (односвязный) список
- •Линейный двунаправленный (двусвязный) список
- •Практическое задание «Линейные списки»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Глава 2 Структуры данных стек и очередь
- •Понятие структуры данных стек и очередь
- •Структура данных стек
- •Структура данных очередь
- •Пример решения задачи с использованием стека
- •Практическое задание «Стеки и очереди»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Глава 3 Древовидные структуры данных
- •Понятие структуры данных дерево
- •Представление структуры бинарное дерево в памяти
- •Обход дерева
- •Основные операции над деревом
- •Ввод дерева
- •Практическое задание «Бинарные деревья»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Глава 4 Структура данных таблица
- •Понятие структуры данных таблица
- •Представление таблицы в памяти
- •Организация хеш-таблиц
- •Выбор функции расстановки
- •Разрешение коллизии
- •Операции над таблицами
- •Практическое задание «Управление таблицами»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Глава 5 Алгоритмы упорядочения данных
- •Понятие операции упорядочения
- •Алгоритмы упорядочения
- •Сортировка слиянием
- •Основные алгоритмы сортировки посредством сравнений
- •Улучшенные алгоритмы сортировки сравнением
- •Практическое задание «Алгоритмы сортировки»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Библиографический список
while (t != NULL)
{
p = t;
t = x > t->elem ? t->right : t->left;
}
x > p->elem ? p->right = r : p->left = r;
}
Ввод дерева
Одним из возможных способов представления дерева для ввода является списочная запись. Изображенное на рис. 3.1, б дерево можно записать в следующем виде:
(A, (B, (D, 0, 0), 0), (C, (E, 0, (G, 0, 0)), (F, (H, 0, 0), (J, 0, 0))))
Ввод дерева, представленного таким списком, реализуется рекурсивной функцией:
tree *BuildTree()
{
char c = 0; scanf(“%c”, &c); switch(c)
{
case ‘(‘: {
tree *t = new tree; scanf(“%c”, &c); t->elem = c;
t->left = BuildTree();
t->right = BuildTree(); scanf(“%c”, &c); return t;
}
case ‘,’: return BuildTree(); case ‘0’: return NULL;
80
default: ;
}
}
ПРАКТИЧЕСКОЕ ЗАДАНИЕ «БИНАРНЫЕ ДЕРЕВЬЯ»
Цели
Изучить основные алгоритмы работы с бинарными деревьями; получить практические навыки разработки и использования этих структур данных и алгоритмов при решении задач.
Варианты заданий
Во всех задачах тип значений элементов дерева простой. Исходное дерево после ввода распечатать в одном из порядков.
1В заданном бинарном дереве подсчитать число его листьев и напечатать их значения:
а) при прямом обходе дерева; б) при обратном обходе дерева; в) при концевом обходе дерева; г) реализуя обход, рекурсивно.
2 В заданном бинарном дереве найти первое вхождение заданного элемента и напечатать пройденные при поиске узлы дерева:
а) при прямом обходе дерева; б) при обратном обходе дерева; в) при концевом обходе дерева; г) реализуя обход, рекурсивно.
3В заданном непустом бинарном дереве найти длину (число ветвей) пути от корня до ближайшей вершины со значением равным заданному:
а) при прямом обходе дерева;
81
б) реализуя обход, рекурсивно.
4В заданном непустом бинарном дереве подсчитать число вершин на n-ом уровне, считая корень вершиной 0-го уровня.
5Задано бинарное дерево. Определить, есть ли в этом дереве хотя бы два одинаковых элемента.
6Распечатать все элементы заданного непустого бинарного дерева по уровням: сначала из корня дерева, затем (слева направо) из вершин, дочерних по отношению к корню, затем (слева направо) из вершин, дочерних по отношению к этим вершинам, и т. д.
7Формулу вида:
<формула > ::= < терминал > (< формула > < знак > < формула >)
<знак > ::= + - *
<терминал > ::= 0 1 2 3 4 5 6 7 8 9
можно представить в виде двоичного дерева (‘дерева – формулы‘):
–формула из одного терминала (цифры) представляется деревом из одной вершины (корнем) с этим терминалом;
–формула вида (f1 s f2) – деревом, в котором корень – это знак s, а левое и правое поддеревья – это соответствующие представления f1 и f2:
а) по заданной формуле построить дерево-формулу, обходя дерево
– формулу в прямом, обратном, концевом порядке; напечатать его элементы и вычислить (как целое число) значение;
б) проверить, является ли заданное двоичное дерево (с элементами типа char) деревом-формулой и напечатать его элементы в порядке прямого, обратного, концевого обхода;
в) пусть в дереве – формуле в качестве терминалов используются не только цифры, но и буквы, играющие роль переменных; преобразовать заданное дерево-формулу, заменяя в нем все поддеревья, соответствующие формулам ((f1 f2) * f3) и (f1 * (f2f3)) на поддеревья, соответствующие формулам ((f1 * f3) ( f2
82
* f3)) и ((f1 * f2) (f1 * f3)); распечатать преобразованное дерево в прямом, обратном и концевом порядках;
г) выполнить в заданном дереве-формуле преобразования, обратные преобразованиям из пункта в); распечатать преобразованное дерево в прямом, обратном и концевом порядках.
8Заданную последовательность из строчных латинских букв, оканчивающуюся точкой, представить в виде дерева поиска, затем преобразовать его, удалив символ с наименьшим, наибольшим значением; распечатать преобразованное дерево в прямом, обратном и концевом порядках.
9Заданную последовательность целых чисел, оканчивающуюся нулем, представить в виде дерева поиска, затем преобразовать его, добавив еще одно целое число; распечатать преобразованное дерево в прямом, обратном и концевом порядках.
Задачи для самостоятельной работы
1Используя очередь или стек (считать уже описанными их типы и операции над ними), опишите на C тип бинарное дерево (считая, что все элементы имеют некоторый простой тип) и реализуйте в виде процедуры или функции одну из перечисленных ниже операций над бинарным деревом (см. рис. 3.2, б).
Используйте наиболее подходящий для решения задачи обход дерева (в глубину: префискный / инфиксный / постфиксный, в ширину):
а) определить входит ли в дерево элемент с заданным значением; б) вычислить сумму всех элементов дерева; в) найти значение самого левого листа непустого дерева;
г) подсчитать число вхождений заданного элемента в дерево;
д) вычислить среднее арифметическое всех элементов непустого дерева;
83
е) заменить в дереве все отрицательные элементы на их абсолютные величины;
ж) найти максимальное значение среди элементов дерева; з) найти минимальное значение среди элементов дерева;
и) поменять местами максимальный и минимальный элементы непустого дерева;
к) напечатать элементы из всех листьев дерева;
л) напечатать элементы дерева по уровням: сначала из корня, затем из вершин, дочерних по отношению к корню, затем из вершин, дочерних по отношению к этим вершинам, и т. д. при этом отделить элементы одного уровня от элементов другого;
м) в непустом дереве найти длину пути от корня до ближайшей вершины с заданным значением;
н) подсчитать число вершин на заданном уровне непустого дерева (корень считать вершиной 0-го уровня);
о) подсчитать число листьев дерева.
2Бинарное дерево T представлено в файле в виде списочной записи (тип элемента дерева задать самостоятельно). Используя очередь или стек и подпрограммы, реализующие операции над ними, решить следующую задачу:
а) определить, входит ли элемент E в двоичное дерево T;
б) определить число вхождений элемента E в двоичное дерево T; в) удалить заданный элемента из бинарного дерева T;
г) найти наибольший и наименьший элементы бинарного дерева
T;
д) вычислить сумму элементов бинарного дерева T;
е) определить, в непустом двоичном дереве T длину (число ветвей) пути от корня дерева до ближайшей вершины с элементом
E;
84
ж) напечатать все элементы непустого двоичного дерева T по уровням: сначала корень дерева, затем (слева направо) вершины дочерние по отношению к корню, затем дочерние по отношению к предшествующему уровню (также слева направо) и т. д., элементы одного уровня печатать в отдельной строке;
з) определить, максимальную глубину непустого двоичного дерева T, т. е. число ветвей в самом длинном из путей от корня дерева до его листьев;
и) определить число вершин на n-ом уровне непустого двоичного дерева T; корень считать вершиной с номером 0;
к) напечатать элементы из всех листьев двоичного дерева T;
л) напечатать элементы на n-ом уровне двоичного дерева T; корень считать вершиной с номером 0;
3Используя рекурсию проверить на равенство два заданных двоичных дерева T1 и T2 (тип элемента дерева задать самостоятельно). В файле дерево представлено в виде списочной записи.
4Используя рекурсию построить копию заданного двоичного дерева T (тип элемента дерева задать самостоятельно). В файле дерево представлено в виде списочной записи.
5В текстовом файле дана последовательность ненулевых целых чисел, оканчивающаяся нулем. Написать подпрограмму, которая помещает элементы этой последовательности в АВЛ-дерево. Напечатать элементы АВЛ-дерева по уровням.
6В файле АВЛ-дерево Т представлено в виде списочной записи (тип элемента дерева задать самостоятельно). Добавить к дереву Т еще
один элемент. Напечатать элементы преобразованного АВЛдерева по уровням.
7 Для бинарного дерева, представленного связным иерархическим списком (см. рис. 3.3), используя очередь или стек описать процедуру или функцию, которая:
85
