Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3 сем / лаб3.docx
Скачиваний:
5
Добавлен:
06.06.2025
Размер:
57.05 Кб
Скачать

Список использованной литературы

  1. Ахо А., Хопкрофт Д., Ульман Дж. Структуры данных и алгоритмы. — М.: Мир, 1986.

  2. Роберт Седжвик. Алгоритмы на C++. Фундаментальные алгоритмы. — М.: Вильямс, 2003.

  3. Дональд Кнут. Искусство программирования. Том 3: Сортировка и поиск. — М.: Вильямс, 2002.

  4. Джосеф А. Р. О'Рурк. Основы алгоритмов и структур данных. — СПб.: Питер, 2010.

  5. Cormen T., Leiserson C., Rivest R., Stein C. Introduction to Algorithms. — MIT Press, 2009.

  6. Документация по C++: https://en.cppreference.com

  7. Документация по STL: https://cplusplus.com/reference/

Приложение

Исходный код программы:

#include <iostream>

#include <queue>

#include <vector>

#include <iomanip>

#include <locale>

#include <random>

using namespace std;

// Класс узла дерева

class TreeNode {

public:

int value; // Значение узла

TreeNode* left; // Левый ребёнок

TreeNode* right; // Правый ребёнок

TreeNode(int val) : value(val), left(nullptr), right(nullptr) {} // Конструктор узла

~TreeNode() = default; // Деструктор узла

};

// Класс двоичного дерева

class BinaryTree {

private:

TreeNode* root; // Корень дерева

// Вспомогательная функция для добавления узла в дерево

void addNode(TreeNode*& current, int value) {

if (!current) {

current = new TreeNode(value);

return;

}

if (value < current->value) {

addNode(current->left, value);

}

else {

addNode(current->right, value);

}

}

// Вспомогательная функция для ширинной разметки

void breadthMark(TreeNode* root) {

if (!root) return;

queue<TreeNode*> q;

q.push(root);

int mark = 1;

while (!q.empty()) {

TreeNode* current = q.front();

q.pop();

current->value = mark++; // Назначаем текущую метку

if (current->left) q.push(current->left);

if (current->right) q.push(current->right);

}

}

// Вспомогательная функция для внутреннего обхода (in-order)

void inOrderTraversal(TreeNode* node, vector<int>& traversal) const {

if (!node) return;

inOrderTraversal(node->left, traversal);

traversal.push_back(node->value);

inOrderTraversal(node->right, traversal);

}

// Вспомогательная функция для подсчёта узлов на нижнем уровне

int countNodesAtBottomLevel(TreeNode* root) const {

if (!root) return 0;

queue<TreeNode*> q;

q.push(root);

int count = 0;

while (!q.empty()) {

int levelSize = q.size();

count = 0;

for (int i = 0; i < levelSize; ++i) {

TreeNode* current = q.front();

q.pop();

count++;

if (current->left) q.push(current->left);

if (current->right) q.push(current->right);

}

}

return count;

}

// Вспомогательная функция для печати дерева

void printTree(TreeNode* node, int space) const {

if (!node) return;

// Увеличиваем расстояние между уровнями

space += 5;

// Сначала выводим правую ветвь

printTree(node->right, space);

// Выводим текущий узел

cout << endl;

for (int i = 5; i < space; ++i) cout << " ";

cout << node->value << "\n";

// Выводим левую ветвь

printTree(node->left, space);

}

public:

BinaryTree() : root(nullptr) {} // Конструктор по умолчанию

// Конструктор с начальным массивом значений

explicit BinaryTree(const vector<int>& values) : root(nullptr) {

for (int val : values) {

addNode(root, val);

}

}

// Деструктор дерева

~BinaryTree() {

deleteTree(root);

}

// Функция для добавления значения в дерево

void insert(int value) {

addNode(root, value);

}

// Функция для ширинной разметки

void markBreadth() {

breadthMark(root);

}

// Функция для внутреннего обхода

vector<int> inOrder() const {

vector<int> traversal;

inOrderTraversal(root, traversal);

return traversal;

}

// Функция для подсчёта узлов на нижнем уровне

int bottomLevelNodeCount() const {

return countNodesAtBottomLevel(root);

}

// Функция для печати дерева

void print() const {

printTree(root, 0);

}

// Генерация случайного дерева

void generateRandomTree(int nodeCount, int minValue, int maxValue) {

random_device rd;

mt19937 gen(rd());

uniform_int_distribution<> dist(minValue, maxValue);

for (int i = 0; i < nodeCount; ++i) {

int randomValue = dist(gen);

insert(randomValue);

}

}

private:

// Вспомогательная функция для удаления дерева

void deleteTree(TreeNode* node) {

if (!node) return;

deleteTree(node->left);

deleteTree(node->right);

delete node;

}

};

int main() {

setlocale(LC_ALL, "russian");

// Инициализация дерева

//vector<int> values = { 10, 5, 15, 3, 7, 12, 18};

//BinaryTree tree(values);

BinaryTree tree;

tree.generateRandomTree(10, 1, 100);

// Ширинная разметка

//tree.markBreadth();

// Печать дерева с разметкой

cout << "Дерево с ширинной разметкой:" << endl;

tree.print();

// Внутренний обход

vector<int> traversal = tree.inOrder();

cout << "\n\nВнутренний обход дерева: ";

for (int val : traversal) {

cout << val << " ";

}

// Подсчёт узлов на нижнем уровне

int bottomNodeCount = tree.bottomLevelNodeCount();

cout << "\n\nКоличество узлов на нижнем уровне: " << bottomNodeCount << endl;

// Инициализация дерева

int nodesCount{};

cout << "Введите кол-во узлов: ";

cin >> nodesCount;

vector<int> values;

cout << "Введите значения узлов: \n";

for (int i = 0; i < nodesCount; ++i) {

int nVal{};

cin >> nVal;

values.push_back(nVal);

}

BinaryTree tree2(values);

// Ширинная разметка

//tree2.markBreadth();

// Печать дерева с разметкой

cout << "Дерево с ширинной разметкой:" << endl;

tree2.print();

// Внутренний обход

vector<int> traversal2 = tree2.inOrder();

cout << "\n\nВнутренний обход дерева: ";

for (int val : traversal2) {

cout << val << " ";

}

// Подсчёт узлов на нижнем уровне

int bottomNodeCount2 = tree2.bottomLevelNodeCount();

cout << "\n\nКоличество узлов на нижнем уровне: " << bottomNodeCount2 << endl;

return 0;

}

Соседние файлы в папке 3 сем