
ТП_23_ИСТ_1_1_Какушкина_Ольга_Витальевна_ЛР_3.2
.docxМИНОБРНАУКИ РОССИИ
Ф
едеральное
государственное бюджетное образовательное
учреждение высшего образования
НИЖЕГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ
УНИВЕРСИТЕТ им. Р.Е.АЛЕКСЕЕВА
Институт радиоэлектроники и информационных технологий
Кафедра информатики и систем управления
ОТЧЕТ по лабораторной работе №3
(наименование темы проекта или работы)
по дисциплине
Технологии программирования
(наименование дисциплины)
РУКОВОДИТЕЛЬ:
________________ Капранов С. Н.
(подпись) (фамилия, и.,о.)
СТУДЕНТ:
________________ Какушкина О.В
(подпись) (фамилия, и.,о.)
23-ИСТ-1-1
(шифр группы)
Работа защищена «___» ____________
С оценкой ________________________
Нижний Новгород 2024
Текст задания:
Задача 7. Дано бинарное дерево. Найти все вершины равноудалённые от корня и от ближайшего своего листа.
Список функций и структур данных с описанием:
struct TreeNode
|
int value; // Значение узла TreeNode* left; // Указатель на левое поддерево TreeNode* right; // Указатель на правое поддерево TreeNode(int val); // Конструктор для создания узла
|
TreeNode* createBinaryTree()
|
Функция для рекурсивного создания бинарного дерева через ввод пользователя. Запрашивает ввод значения узла у пользователя. Если введено значение -1, создается пустой узел. Рекурсивно создает левое и правое поддерево. Возвращает указатель на корень созданного дерева.
|
TreeNode* createBinaryTreeFromFile(ifstream& inputFile)
|
Функция для создания бинарного дерева из файла. Считывает значение узла из файла. Если значение равняется -1, возвращается пустой узел. Рекурсивно создает левое и правое поддерево. Возвращает указатель на корень созданного дерева или nullptr при ошибке.
|
int findDistanceToNearestLeaf(TreeNode* node, int depth)
|
Рекурсивная функция для поиска расстояния до ближайшего листа. Параметры: TreeNode* node: указатель на текущий узел. int depth: текущее значение глубины. Возвращает минимальную глубину листа дерева.
|
void findEqualDistanceNodes(TreeNode* node, int distanceFromRoot)
|
Функция находит узлы, равноудаленные от корня и ближайшего листа. Параметры: TreeNode* node: указатель на текущий узел. int distanceFromRoot: расстояние от корня до текущего узла. Выводит значения узлов, которые находятся на равном расстоянии от корня и ближайшего листа.
|
Программный код:
#include <iostream>
#include <fstream>
#include <limits.h>
using namespace std;
struct TreeNode {
int value;
TreeNode* left;
TreeNode* right;
TreeNode(int val) : value(val), left(nullptr), right(nullptr) {}
};
// Функция для создания бинарного дерева через ввод пользователя
TreeNode* createBinaryTree() {
int value;
while (true) {
cout << "Введите значение узла (целое число, -1 для пустого узла): ";
if (!(cin >> value) || (value < -1)) {
cout << "Ошибка: некорректное значение. Пожалуйста, вводите только целые числа!" << endl;
cin.clear(); // очищаем флаг ошибки ввода
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // очищаем буфер ввода
}
else {
break; // значение корректное, выходим из цикла
}
}
// Если вводится -1, то узел пустой
if (value == -1) {
return nullptr;
}
// Создаем узел
TreeNode* node = new TreeNode(value);
// Рекурсивно создаем левое и правое поддерево для данного узла
cout << "Левое поддерево для " << value << ":\n";
node->left = createBinaryTree();
cout << "Правое поддерево для " << value << ":\n";
node->right = createBinaryTree();
return node;
}
// Функция для создания бинарного дерева из файла
TreeNode* createBinaryTreeFromFile(ifstream& inputFile) {
int value;
if (!(inputFile >> value)) {
cout << "Ошибка, некорректное число в файле!" << endl;
return nullptr; // Возвращаем nullptr для некорректного ввода
}
// Если вводится -1, то узел пустой
if (value == -1) {
return nullptr;
}
// Создаем узел
TreeNode* node = new TreeNode(value);
node->left = createBinaryTreeFromFile(inputFile);
node->right = createBinaryTreeFromFile(inputFile);
return node;
}
// Рекурсивная функция для нахождения расстояния до ближайшего листа
int findDistanceToNearestLeaf(TreeNode* node, int depth) {
if (!node) return INT_MAX;
if (!node->left && !node->right) return depth;
return min(findDistanceToNearestLeaf(node->left, depth + 1),
findDistanceToNearestLeaf(node->right, depth + 1));
}
// Функция для нахождения вершин, равноудаленных от корня и ближайшего листа
void findEqualDistanceNodes(TreeNode* node, int distanceFromRoot) {
if (!node) return;
int distanceToLeaf = findDistanceToNearestLeaf(node, 0);
if (distanceFromRoot == distanceToLeaf) {
cout << node->value << " ";
}
findEqualDistanceNodes(node->left, distanceFromRoot + 1);
findEqualDistanceNodes(node->right, distanceFromRoot + 1);
}
int main() {
setlocale(LC_ALL, "Russian");
TreeNode* root = nullptr;
int choice; // Параметр выбора
while (true) {
cout << "Выберите метод создания бинарного дерева:\n";
cout << "1. Ввод значений вручную\n";
cout << "2. Чтение значений из файла\n";
cout << "0. Выход\n";
// Проверяем корректность ввода
while (!(cin >> choice)) {
cout << "Ошибка: неверный ввод. Пожалуйста, введите целое число." << endl;
cin.clear(); // Очищаем флаг ошибки ввода
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Очищаем буфер ввода
}
switch (choice) {
case 1:
root = createBinaryTree();
break;
case 2: {
string filename;
cout << "Введите полное имя файла (например, C:/Users/79081/...): ";
cin >> filename;
ifstream inputFile(filename);
if (!inputFile) {
cout << "Ошибка: не удалось открыть файл: " << filename << endl;
continue; // Возвращаемся к выбору меню
}
root = createBinaryTreeFromFile(inputFile);
inputFile.close();
break;
}
case 0:
cout << "Выход из программы." << endl;
return 0; // Завершаем программу
default:
cout << "Неверный выбор. Попробуйте снова." << endl; // Сообщаем об ошибке
continue; // Возвращаемся к выбору меню
}
// Вывод результатов найденных вершин после создания дерева
cout << "Вершины, равноудаленные от корня и ближайшего листа:\n";
findEqualDistanceNodes(root, 0);
cout << endl;
// Освобождение памяти
delete root;
root = nullptr; // Сбрасываем указатель в nullptr
}
}
Файл:
Вывод в консоли:
Ввод с клавиатуры и чтение из файла
Некорректные данные с клавиатуры
Некорректные данные с файла
Вывод:
Эта лабораторная работа позволила лучше понять, как работают бинарные деревья и как можно манипулировать данными для их создания и анализа. Также были закреплены навыки обработки ошибок ввода, что важно для создания устойчивых к действиям пользователя программ.
Таким образом, данное задание предоставило как теоретическую, так и практическую основу для понимания работы с структурами данных – бинарные деревья.