
ТП_23_ИСТ_1_1_Какушкина_Ольга_Витальевна_ЛР_4.2
.docxМИНОБРНАУКИ РОССИИ
Ф
едеральное
государственное бюджетное образовательное
учреждение высшего образования
НИЖЕГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ
УНИВЕРСИТЕТ им. Р.Е.АЛЕКСЕЕВА
Институт радиоэлектроники и информационных технологий
Кафедра информатики и систем управления
ОТЧЕТ по лабораторной работе №4
(наименование темы проекта или работы)
по дисциплине
Технологии программирования
(наименование дисциплины)
РУКОВОДИТЕЛЬ:
________________ Капранов С. Н.
(подпись) (фамилия, и.,о.)
СТУДЕНТ:
________________ Какушкина О.В
(подпись) (фамилия, и.,о.)
23-ИСТ-1-1
(шифр группы)
Работа защищена «___» ____________
С оценкой ________________________
Нижний Новгород 2024
Текст задания:
Задача 7. Дано N-дерево. Найти все вершины с одинаковыми номерами.
Список функций и структур данных с описанием:
struct Node |
Структура, представляющая узел дерева. Каждый узел содержит значение и вектор дочерних узлов. int value: Значение узла. vector<Node*> children: Вектор указателей на дочерние узлы
|
Node* createTreeFromInput():
|
Создаёт дерево на основе пользовательского ввода. Возвращаемое значение: Указатель на корень дерева типа Node или nullptr, если количество узлов равно 0. Запрашивает у пользователя количество узлов, значения узлов и индексы родителей, формируя дерево.
|
void findDuplicates(Node* root, unordered_map<int, vector<Node*>>& duplicates): |
Обходит дерево и находит дубликаты значений узлов. Параметры: Node* root: Указатель на корень дерева. unordered_map<int, vector<Node*>>& duplicates: Словарь, где ключ — значение узла, а значение — вектор узлов с этим значением. Задача: Использует обход дерева, добавляя узлы с одинаковыми значениями в словарь.
|
void printTree(Node* root, int level = 0) |
Выводит дерево на экран с отступами для визуализации уровня вложенности. Параметры: Node* root: Указатель на корень дерева. int level: Уровень вложенности (по умолчанию 0). Задача: Рекурсивно выводит значения узлов, отображая структуру дерева.
|
Программный код:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <fstream>
#include <limits>
#include <string>
using namespace std;
struct Node {
int value;
vector<Node*> children;
Node(int val) : value(val) {}
};
// Функция для создания дерева из файла
Node* createTreeFromFile(ifstream& file) {
int n;
file >> n; // Читаем количество узлов
if (n == 0) return nullptr;
vector<Node*> nodes(n);
for (int i = 0; i < n; ++i) {
int value;
file >> value;
nodes[i] = new Node(value);
}
int parentIndex;
for (int i = 1; i < n; ++i) {
file >> parentIndex; // Читаем индекс родителя
nodes[parentIndex]->children.push_back(nodes[i]); // Добавляем ребенка к родителю
}
return nodes[0]; // Возвращаем корень
}
// Функция для создания дерева с помощью пользовательского ввода
Node* createTreeFromInput() {
int n;
cout << "Введите количество узлов в дереве: ";
cin >> n;
if (n == 0) return nullptr;
vector<Node*> nodes(n);
for (int i = 0; i < n; ++i) {
int value;
cout << "Введите значение узла " << i << ": ";
cin >> value;
nodes[i] = new Node(value);
}
int parentIndex;
for (int i = 1; i < n; ++i) {
cout << "Введите индекс родителя для узла " << i << ": ";
cin >> parentIndex;
nodes[parentIndex]->children.push_back(nodes[i]);
}
return nodes[0]; // Возвращаем корень
}
// Функция для обхода дерева и поиска дубликатов
void findDuplicates(Node* root, unordered_map<int, vector<Node*>>& duplicates) {
if (!root) return;
duplicates[root->value].push_back(root);
for (Node* child : root->children) {
findDuplicates(child, duplicates);
}
}
// Функция для вывода дерева
void printTree(Node* root, int level = 0) {
if (!root) return;
cout << string(level * 2, ' ') << root->value << endl;
for (Node* child : root->children) {
printTree(child, level + 1);
}
}
int main() {
setlocale(LC_ALL, "Russian");
Node* root = nullptr;
while (true) {
cout << "Выберите метод создания N-дерева:\n";
cout << "1. Ввод значений вручную\n";
cout << "2. Чтение значений из файла\n";
cout << "0. Выход\n";
int choice;
// Проверяем корректность ввода
while (!(cin >> choice)) {
cout << "Ошибка: неверный ввод. Пожалуйста, введите целое число." << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
switch (choice) {
case 1:
root = createTreeFromInput();
break;
case 2: {
string filename;
cout << "Введите полное имя файла (например, C:/Users/79081/...): ";
cin >> filename;
ifstream inputFile(filename);
if (!inputFile) {
cout << "Ошибка: не удалось открыть файл: " << filename << endl;
continue;
}
root = createTreeFromFile(inputFile);
inputFile.close();
break;
}
case 0:
cout << "Выход из программы." << endl;
return 0;
default:
cout << "Неверный выбор. Попробуйте снова." << endl;
continue;
}
// Выводим дерево и дубликаты после его создания
if (root) {
cout << "Дерево:" << endl;
printTree(root);
unordered_map<int, vector<Node*>> duplicates;
findDuplicates(root, duplicates);
cout << "Вершины с одинаковыми номерами:" << endl;
for (const auto& pair : duplicates) {
if (pair.second.size() > 1) {
cout << "Значение " << pair.first;
cout << endl;
}
}
}
else {
cout << "Ошибка при создании дерева." << endl;
}
}
return 0;}
Файл:
Вывод в консоли:
Ввод с клавиатуры и чтение из файла
Некорректные данные с клавиатуры
Некорректные данные с файла
Вывод:
В данной лабораторной работе была разработана программа на языке C++, реализующая структуру данных N-дерево с использованием рекурсивного подхода. При помощи метода обхода в глубину (DFS) программа находит и выводит все узлы с одинаковыми значениями. Это позволяет анализировать структуру дерева на наличие повторяющихся элементов. Данный алгоритм позволяет обойти дерево за O(N), что оптимально для данной задачи.