Добавил:
YunonaKuzmicheva
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:деревья код
.txt#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <stack>
#include <queue>
#include <conio.h>
using namespace std;
/////////////////////////////////// обычное дерево, парсинг
struct NodeB //структура обычного двоичного дерева
{
int data;
NodeB* left;
NodeB* right;
NodeB* parent;
NodeB(int value, NodeB* parentNode = nullptr)
: data(value), parent(parentNode), left(nullptr), right(nullptr) {}
};
void preOrderTravers(NodeB*& root) //прямой обход в глубину
{
if (root)
{
cout << root->data << " ";
preOrderTravers(root->left);
preOrderTravers(root->right);
}
}
NodeB* parseTree(const std::string& str, size_t& i, NodeB* parent = nullptr)
{
if (i >= str.size()) {
return nullptr;
}
char value = str[i];
if (value == '(') {
i++; // Пропуск открывающей скобки
int nodeValue = str[i++] - '0';
while (str[i] >= '0' && str[i] <= '9') {
nodeValue = nodeValue * 10 + (str[i++] - '0');
}
NodeB* newNode = new NodeB(nodeValue, parent);
newNode->left = parseTree(str, i, newNode);
newNode->right = parseTree(str, i, newNode);
i++; // Пропуск закрывающей скобки
return newNode;
}
return nullptr;
}
void addElement(int value, NodeB*& root) //добавление
{
if (!root)
{
root = new NodeB(value);
root->data = value;
root->left = 0;
root->right = 0;
return;
}
if (root->data > value)
{
addElement(value, root->left);
}
else if (root->data < value)
{
addElement(value, root->right);
};
}
//////////////////// вывод
struct Trunk
{
Trunk* prev;
string str;
Trunk(Trunk* prev, string str)
{
this->prev = prev;
this->str = str;
}
};
void showTrunks(Trunk* p)
{
if (p == nullptr) {
return;
}
showTrunks(p->prev);
cout << p->str;
}
void printTree(NodeB* root, Trunk* prev, bool isLeft)
{
if (root == nullptr) {
return;
}
string prev_str = " ";
Trunk* trunk = new Trunk(prev, prev_str);
printTree(root->right, trunk, true);
if (!prev) {
trunk->str = "___";
}
else if (isLeft)
{
trunk->str = ".---";
prev_str = " |";
}
else {
trunk->str = "`___";
prev->str = prev_str;
}
showTrunks(trunk);
cout << " " << root->data << endl;
if (prev) {
prev->str = prev_str;
}
trunk->str = " |";
printTree(root->left, trunk, false);
}
void printTrees(NodeB* root, int indent = 0)
{
if (root == nullptr)
{
return;
}
printTrees(root->right, indent + 4);// Вывод правой ветки дерева
for (int i = 0; i < indent; i++) // Вывод текущего узела
{
std::cout << " ";
}
cout << root->data << endl;
printTrees(root->left, indent + 4);// Вывод левой ветки дерева
}
////////////////////////////////////////// авл-дерево
struct NodeAVL
{
int height;
int value;
NodeAVL* left;
NodeAVL* right;
};
NodeAVL* createAVL(int value) {
NodeAVL* root = new NodeAVL;
root->left = NULL;
root->right = NULL;
root->height = 0;
root->value = value;
return root;
}
// Минимальный элемент в АВЛ-дереве
NodeAVL* getMinAVL(NodeAVL* root) {
while (root->left)
root = root->left;
return root;
}
// Поиск в АВЛ-дереве значения
NodeAVL* searchAVL(int value, NodeAVL* root) {
if (root != nullptr) {
if (value == root->value)
return root;
if (value < root->value)
return searchAVL(value, root->left);
else
return searchAVL(value, root->right);
}
else return NULL;
}
// Получить высоту АВЛ-узла (если узел == null, высота равна 0)
int heightAVL(NodeAVL* node) {
return node == NULL ? 0 : node->height;
}
// Получить фактор сбалансированности АВЛ-узла (если узел == null, фактор равен 0)
int bfactorAVL(NodeAVL* node) {
return node == NULL ? 0 : (heightAVL(node->right) - heightAVL(node->left));
}
// Пересчитать высоту АВЛ-узла и записать в node->height
void recalcHeightAVL(NodeAVL* node) {
int hl = heightAVL(node->left);
int hr = heightAVL(node->right);
node->height = (hl > hr ? hl : hr) + 1;
}
// Малое правое вращение
NodeAVL* rotrightAVL(NodeAVL* node)
{
NodeAVL* ltree = node->left;
NodeAVL* subtree = ltree->right;
ltree->right = node;
node->left = subtree;
recalcHeightAVL(node);
recalcHeightAVL(ltree);
return ltree;
}
// Малое левое вращение
NodeAVL* rotleftAVL(NodeAVL* node)
{
NodeAVL* rtree = node->right;
NodeAVL* subtree = rtree->left;
rtree->left = node;
node->right = subtree;
recalcHeightAVL(node);
recalcHeightAVL(rtree);
return rtree;
}
// Сбалансировать узел
NodeAVL* balanceAVL(NodeAVL* node) {
recalcHeightAVL(node);
if (bfactorAVL(node) == 2) {
if (bfactorAVL(node->right) < 0)
node->right = rotrightAVL(node->right);
return rotleftAVL(node);
}
if (bfactorAVL(node) == -2) {
if (bfactorAVL(node->left) > 0)
node->left = rotleftAVL(node->left);
return rotrightAVL(node);
}
return node;
}
// Удаление элемента из АВЛ-дерева
NodeAVL* deleteAVL(int value, NodeAVL* root) {
if (root == NULL)
return NULL;
if (value < root->value)
root->left = deleteAVL(value, root->left);
else if (value > root->value)
root->right = deleteAVL(value, root->right);
else {
if (root->left == NULL && root->right == NULL)
root = NULL;
else if (root->left == NULL || root->right == NULL)
root = root->left ? root->left : root->right;
else {
NodeAVL* minnode = getMinAVL(root->right);
root->value = minnode->value;
root->right = deleteAVL(minnode->value, root->right);
}
}
return root ? balanceAVL(root) : NULL;
}
// Добавить значение в АВЛ-дерево (root != null)
NodeAVL* insertAVL(int value, NodeAVL* root) {
if (!root) {
root = new NodeAVL;
root->value = value;
root->height = 1;
root->left = NULL;
root->right = NULL;
return root;
}
if (value < root->value)
root->left = insertAVL(value, root->left);
else if (value > root->value)
root->right = insertAVL(value, root->right);
return balanceAVL(root);
}
// Добавить значение в АВЛ-дерево
void addAVL(int value, NodeAVL*& root) {
if (root == NULL)
root = createAVL(value);
else
root = insertAVL(value, root);
}
// Straight-walk: Прямой обход АВЛ-дерева
void strwAVL(NodeAVL* root) {
if (root) {
std::cout << root->value << ' ';
strwAVL(root->left);
strwAVL(root->right);
}
}
// Reverse-walk: Обратный обход АВЛ-дерева
void revwAVL(NodeAVL* root) {
if (root) {
revwAVL(root->left);
revwAVL(root->right);
std::cout << root->value << ' ';
}
}
// Symmetrical-walk: Симметричный обход АВЛ-дерева
void symwAVL(NodeAVL* root) {
if (root) {
symwAVL(root->left);
std::cout << root->value << ' ';
symwAVL(root->right);
}
}
void breadthFirstUtil(NodeAVL* head) //в ширину
{
if (!head) return;
std::queue<NodeAVL*> q;
q.push(head);
while (!q.empty()) {
NodeAVL* curr = q.front();
q.pop();
std::cout << curr->value << ' ';
if (curr->left) q.push(curr->left);
if (curr->right) q.push(curr->right);
}
}
void printTreeAVL(NodeAVL* root, Trunk* prev, bool isLeft)
{
if (root == nullptr) {
return;
}
string prev_str = " ";
Trunk* trunk = new Trunk(prev, prev_str);
printTreeAVL(root->right, trunk, true);
if (!prev) {
trunk->str = "___";
}
else if (isLeft)
{
trunk->str = ".---";
prev_str = " |";
}
else {
trunk->str = "`___";
prev->str = prev_str;
}
showTrunks(trunk);
cout << " " << root->value << endl;
if (prev) {
prev->str = prev_str;
}
trunk->str = " |";
printTreeAVL(root->left, trunk, false);
}
vector<int> convertToVector(NodeB* root) {
vector<int> arr;
stack<NodeB*> nodes;
NodeB* current = root;
while (current != NULL || !nodes.empty()) {
while (current != NULL) {
nodes.push(current);
current = current->left;
}
current = nodes.top();
nodes.pop();
arr.push_back(current->data);
current = current->right;
}
return arr;
}
int main()
{
bool flag = false;
bool work = false;
while (!flag)
{
setlocale(LC_ALL, "Russian");
///////обычное дерево
char strTree[1000];
string str;
ifstream f1;
int open = 0, close = 0;
f1.open("file.txt");
if (!f1.is_open())
{
cout << "Ошибка чтения файла" << endl;
return 0;
}
else
{
f1.getline(strTree, 1000);
int i = 0, j = 0;
while (strTree[i] != '\0')
{
if (strTree[i] != ' ')
{
if (strTree[i] == '(')
{
open++;
}
else if (strTree[i] == ')')
{
close++;
}
if (open < close)
{
cout << "Неверная запись в файле" << endl;
return 0;
}
str += strTree[i];
if (str[j] != '-' && str[j] != '(' && str[j] != ')')
{
if (str[j] < '0' || str[j] > '9')
{
cout << "Неверная запись в файле" << endl;
return 0;
}
}
j++;
}
i++;
}
if (open != close)
{
cout << "Неверная запись в файле" << endl;
return 0;
}
f1.close();
}
size_t index = 0;
NodeB* root2 = parseTree(str, index);
////////////// авл
NodeB* root = 0;
ifstream inputFile("file.txt");
if (!inputFile) {
cout << "Не удалось открыть файл!" << std::endl;
return 1;
}
string line;
getline(inputFile, line);
string numberString;
int i = 0;
bool bruh = true;
while (i < line.length()) {
if (isdigit(line[i])) {
numberString += line[i];
}
else if (!numberString.empty()) {
addElement(stoi(numberString), root);
numberString.clear();
}
else if (line[i] != '(' && line[i] != ')' && line[i] != ' ') {
bruh = false;
break;
}
i++;
}
if (!bruh)
{
cout << "Ваш файл содержит запрещённые символы!\n";
system("pause");
break;
}
NodeAVL* avl = 0;
vector<int> arr = convertToVector(root);
for (int num : arr)
{
addAVL(num, avl);
}
///////////////////////////////
char key{};
int a = 0;
system("cls");
work = false;
int strel = 1;
while (!work)
{
system("cls");
cout << "3 лаба";
cout << "\n\n\n";
cout << "Ваше введённое дерево (из файла):\n\n";
printTree(root2, nullptr, false);
//printTrees(root2);
cout << "\n";
cout << "Ваше дерево, преобразованное в АВЛ:\n\n";
printTreeAVL(avl, nullptr, false);
cout << "\n\n";
cout << "Выберите действие стрелкой и нажмите enter";
cout << "\n\n";
cout << "Добавить элемент в дерево";
if (strel == 1) cout << " <--";
cout << "\n";
cout << "Удалить элемент из дерева";
if (strel == 2) cout << " <--";
cout << "\n";
cout << "Найти элемент в дереве";
if (strel == 3) cout << " <--";
cout << "\n";
cout << "Прямой обход дерева";
if (strel == 4) cout << " <--";
cout << "\n";
cout << "Обратный обход дерева";
if (strel == 5) cout << " <--";
cout << "\n";
cout << "Симметричный обход дерева";
if (strel == 6) cout << " <--";
cout << "\n";
cout << "Обход дерева в ширину";
if (strel == 7) cout << " <--";
cout << "\n";
cout << "Выход";
if (strel == 8) cout << " <--";
cout << "\n";
key = _getch();
if (int(key) == -32)
{
rewind(stdin);
key = _getch();
system("cls");
}
if (key == 'P')
{
strel += 1;
if (strel > 8) strel = 1;
continue;
system("cls");
}
if (key == 'H')
{
strel -= 1;
if (strel < 1) strel = 8;
continue;
system("cls");
}
//system("cls");
if (strel == 1 and key == '\r')
{
cout << "\n";
int i = 0;
while (!(cin >> i) || (cin.peek() != '\n'))
{
cout << "Неверный формат данных. Пожалуйста, повторите попытку\n";
printf("Введите число которое Вы хотите ввести\t");
cin.clear();
rewind(stdin);
}
addAVL(i, avl);
}
if (strel == 2 and key == '\r')
{
cout << "\n";
int i = 0;
while (!(cin >> i) || (cin.peek() != '\n'))
{
cout << "Неверный формат данных. Пожалуйста, повторите попытку\n";
printf("Введите число которое Вы хотите удалить\t");
cin.clear();
rewind(stdin);
}
avl = deleteAVL(i, avl);
}
if (strel == 3 and key == '\r')
{
cout << "\n";
int i = 0;
while (!(cin >> i) || (cin.peek() != '\n'))
{
cout << "Неверный формат данных. Пожалуйста, повторите попытку\n";
printf("Введите число которое Вы хотите найти\t");
cin.clear();
rewind(stdin);
}
NodeAVL* node = searchAVL(i, avl); //поиск
if (node != NULL)
cout << "Элемент найден: " << node->value << endl;
else
cout << "Элемент не найден!" << endl;
cout << "\n";
system("pause");
}
if (strel == 4 and key == '\r')
{
cout << "\n";
strwAVL(avl);
cout << "\n";
system("pause");
}
if (strel == 5 and key == '\r')
{
cout << "\n";
revwAVL(avl);
cout << "\n";
system("pause");
}
if (strel == 6 and key == '\r')
{
cout << "\n";
symwAVL(avl);
cout << "\n";
system("pause");
}
if (strel == 7 and key == '\r')
{
cout << "\n";
breadthFirstUtil(avl);
cout << "\n";
system("pause");
}
if ((strel == 8 and key == '\r') or (key == '\x1B'))
{
flag = true;
break;
}
}
}
return 0;
}
Соседние файлы в предмете Алгоритмы и системы данных
