Задания по построению двоичного дерева и обходам дерева
Обход двоичного дерева, сверху-вниз, слева-направо снизу-вверх.
Требования к заданию
Варианты деревьев
Пособие стр. 41
Ход выполнения
Начало файла, константы и вспомогательные функции
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct Vertex {
int data;
struct Vertex *left;
struct Vertex *right;
} Vertex;
int tree_height(Vertex *root) {
if (root == NULL) {
return 0;
}
int lh = tree_height(root->left);
int rh = tree_height(root->right);
return 1 + (lh > rh ? lh : rh);
}
int tree_checksum(Vertex *root) {
if (root == NULL) {
return 0;
}
return root->data + tree_checksum(root->left) + tree_checksum(root->right);
}
int tree_size(Vertex *root) {
if (root == NULL) {
return 0;
}
return 1 + tree_size(root->left) + tree_size(root->right);
}
int tree_sum_path_lengths(Vertex *root, int depth) {
if (root == NULL) {
return 0;
}
return depth + tree_sum_path_lengths(root->left, depth + 1) +
tree_sum_path_lengths(root->right, depth + 1);
}
float tree_average_height(Vertex *root) {
if (root == NULL) {
return 0;
}
return (float)tree_sum_path_lengths(root, 1) / tree_size(root);
}
- Разместить в памяти компьютера заданное двоичное дерево
(см. ниже, номер варианта соответствует номеру студента в журнале группы),
данные в вершинах заполнить целыми числами (в диапазоне от 1 до 20).
/*
Дерево для 7 варианта
1
/ \
2 3
/ \
4 5
/ \
6 7
*/
void init_tree(Vertex *root) {
srand(time(NULL));
root->data = (rand() + 1) % 21;
root->left = (Vertex *)malloc(sizeof(Vertex));
root->left->data = (rand() + 1) % 21;
root->right = (Vertex *)malloc(sizeof(Vertex));
root->right->data = (rand() + 1) % 21;
root->right->right = (Vertex *)malloc(sizeof(Vertex));
root->right->right->data = (rand() + 1) % 21;
root->right->right->left = (Vertex *)malloc(sizeof(Vertex));
root->right->right->left->data = (rand() + 1) % 21;
root->right->right->right = (Vertex *)malloc(sizeof(Vertex));
root->right->right->right->data = (rand() + 1) % 21;
}
- Запрограммировать обходы двоичного дерева сверху вниз, слева направо и снизу вверх,
и вывести на экран получившиеся последовательности данных.
// Root, L, R
void tree_traversal_downward(Vertex *root) {
if (root != NULL) {
printf("%d ", root->data);
tree_traversal_downward(root->left);
tree_traversal_downward(root->right);
}
}
// L, Root, R
void tree_traversal_rightward(Vertex *root) {
if (root != NULL) {
tree_traversal_rightward(root->left);
printf("%d ", root->data);
tree_traversal_rightward(root->right);
}
}
// L, R, Root
void tree_traversal_upward(Vertex *root) {
if (root != NULL) {
tree_traversal_upward(root->left);
tree_traversal_upward(root->right);
printf("%d ", root->data);
}
}
- Для построенного дерева вычислить размер, контрольную сумму, высоту и среднюю высоту.
(Для средней высоты предусмотреть вывод двух знаков после запятой).
int main() {
Vertex *root = (Vertex *)malloc(sizeof(Vertex));
init_tree(root);
printf("\033[32m \033[21mОбход сверху-вниз:\033[0m\n");
tree_traversal_downward(root);
printf("\n\033[32m \033[21mОбход слева-направо:\033[0m\n");
tree_traversal_rightward(root);
printf("\n\033[32m \033[21mОбход снизу-вверх:\033[0m\n");
tree_traversal_upward(root);
printf("\n");
printf("\nРазмер дерева: %d", tree_size(root));
printf("\nКонтрольная сумма дерева: %d", tree_checksum(root));
printf("\nВысота дерева: %d", tree_height(root));
printf("\nСредняя высота дерева: %.2f\n", tree_average_height(root));
return 0;
}
- Освоить написание вручную обходов любого заданного двоичного дерева.
См. пособие и варианты заданий по обработке деревьев.
Полный текст программы
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct Vertex {
int data;
struct Vertex *left;
struct Vertex *right;
} Vertex;
/*
Дерево для 7 варианта
1
/ \
2 3
/ \
4 5
/ \
6 7
*/
void init_tree(Vertex *root) {
srand(time(NULL));
root->data = (rand() + 1) % 21;
root->left = (Vertex *)malloc(sizeof(Vertex));
root->left->data = (rand() + 1) % 21;
root->right = (Vertex *)malloc(sizeof(Vertex));
root->right->data = (rand() + 1) % 21;
root->right->right = (Vertex *)malloc(sizeof(Vertex));
root->right->right->data = (rand() + 1) % 21;
root->right->right->left = (Vertex *)malloc(sizeof(Vertex));
root->right->right->left->data = (rand() + 1) % 21;
root->right->right->right = (Vertex *)malloc(sizeof(Vertex));
root->right->right->right->data = (rand() + 1) % 21;
}
int tree_height(Vertex *root) {
if (root == NULL) {
return 0;
}
int lh = tree_height(root->left);
int rh = tree_height(root->right);
return 1 + (lh > rh ? lh : rh);
}
int tree_checksum(Vertex *root) {
if (root == NULL) {
return 0;
}
return root->data + tree_checksum(root->left) + tree_checksum(root->right);
}
int tree_size(Vertex *root) {
if (root == NULL) {
return 0;
}
return 1 + tree_size(root->left) + tree_size(root->right);
}
int tree_sum_path_lengths(Vertex *root, int depth) {
if (root == NULL) {
return 0;
}
return depth + tree_sum_path_lengths(root->left, depth + 1) +
tree_sum_path_lengths(root->right, depth + 1);
}
float tree_average_height(Vertex *root) {
if (root == NULL) {
return 0;
}
return (float)tree_sum_path_lengths(root, 1) / tree_size(root);
}
// Root, L, R
void tree_traversal_downward(Vertex *root) {
if (root != NULL) {
printf("%d ", root->data);
tree_traversal_downward(root->left);
tree_traversal_downward(root->right);
}
}
// L, Root, R
void tree_traversal_rightward(Vertex *root) {
if (root != NULL) {
tree_traversal_rightward(root->left);
printf("%d ", root->data);
tree_traversal_rightward(root->right);
}
}
// L, R, Root
void tree_traversal_upward(Vertex *root) {
if (root != NULL) {
tree_traversal_upward(root->left);
tree_traversal_upward(root->right);
printf("%d ", root->data);
}
}
int main() {
Vertex *root = (Vertex *)malloc(sizeof(Vertex));
init_tree(root);
printf("\033[32m \033[21mОбход сверху-вниз:\033[0m\n");
tree_traversal_downward(root);
printf("\n\033[32m \033[21mОбход слева-направо:\033[0m\n");
tree_traversal_rightward(root);
printf("\n\033[32m \033[21mОбход снизу-вверх:\033[0m\n");
tree_traversal_upward(root);
printf("\n");
printf("\nРазмер дерева: %d", tree_size(root));
printf("\nКонтрольная сумма дерева: %d", tree_checksum(root));
printf("\nВысота дерева: %d", tree_height(root));
printf("\nСредняя высота дерева: %.2f\n", tree_average_height(root));
return 0;
}