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

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

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

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

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

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

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

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

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

ОТЧЕТ по лабораторной работе №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), что оптимально для данной задачи.