Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ТП_23_ИСТ_1_1_Какушкина_Ольга_Витальевна_ЛР_3.2

.docx
Скачиваний:
0
Добавлен:
23.06.2025
Размер:
261.14 Кб
Скачать

МИНОБРНАУКИ РОССИИ

Ф едеральное государственное бюджетное образовательное учреждение высшего образования

НИЖЕГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ

УНИВЕРСИТЕТ им. Р.Е.АЛЕКСЕЕВА

Институт радиоэлектроники и информационных технологий

Кафедра информатики и систем управления

ОТЧЕТ по лабораторной работе №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

}

}

Файл:

Вывод в консоли:

Ввод с клавиатуры и чтение из файла

Некорректные данные с клавиатуры

Некорректные данные с файла

Вывод:

Эта лабораторная работа позволила лучше понять, как работают бинарные деревья и как можно манипулировать данными для их создания и анализа. Также были закреплены навыки обработки ошибок ввода, что важно для создания устойчивых к действиям пользователя программ.

Таким образом, данное задание предоставило как теоретическую, так и практическую основу для понимания работы с структурами данных – бинарные деревья.