#include <stdio.h>
#include <conio.h>
#include <Windows.h>
struct Node {
char s[81];
Node *left, *right;
Node():left(NULL), right(NULL) {}
void DestructorWithoutSubTree()
{
left = NULL;
right = NULL;
delete this;
}
~Node()
{
if (left) delete left;
if (right) delete right;
left = NULL;
right = NULL;
}
};
class BTree
{
Node* root;
size_t count;
void Insert(Node *Tree, char *s)
{
if (strcmp(s, Tree->s) >= 0)
{
if (!Tree->right)
{
Node *n = new Node;
strcpy(n->s, s);
Tree->right = n;
}
else Insert(Tree->right, s);
}
else
{
if (!Tree->left)
{
Node *n = new Node;
strcpy(n->s, s);
Tree->left = n;
}
else Insert(Tree->left, s);
}
}
public:
BTree() :root(NULL),count(0) {};
~BTree()
{
delete root;
root = NULL;
count = 0;
}
size_t Size()
{
return count;
}
bool Search(Node *Tree, char *s)
{
if (strcmp(s, Tree->s) == 0) return true;
else if (strcmp(s, Tree->s) > 0)
{
if (!Tree->right) return false;
else return Search(Tree->right, s);
}
else
{
if (!Tree->left) return false;
else return Search(Tree->left, s);
}
}
bool Search(char *s)
{
return Search(root, s);
}
void Insert(char *s)
{
if(root)
Insert(root, s);
else
{
Node *n = new Node;
strcpy(n->s, s);
root = n;
}
count++;
}
Node * FindParent(Node *parent, Node *n)
{
if (parent->left == n || parent->right == n) return parent;
else
{
Node *tmp = new Node;
tmp = NULL;
if (parent->left) tmp=FindParent(parent->left, n);
if (parent->right && !tmp) tmp= FindParent(parent->right, n);
return tmp;
}
}
Node * FindParent( Node *n)
{
return FindParent(root, n);
}
void Delete(size_t i)
{
Node *n = (*this)[i];
Node *parent = this->FindParent(n);
if (!n->left && !n->right)
{
if (parent->left == n) parent->left = NULL;
if (parent->right == n) parent->right = NULL;
if (!parent) root = NULL;
delete n;
}
else if ((!n->left) != (!n->right))
{
if (parent->left == n)
{
if(n->left)
parent->left = n->left;
else parent->left = n->right;
}
if (parent->right == n) {
if (n->left)
parent->right = n->left;
else parent->right = n->right;
}
if (!parent) root = n->left ? n->left : n->right;
n->DestructorWithoutSubTree();
}
else
{
size_t *ptr = new size_t;
*ptr = 0;
Node *tmp=this->At(n->right,ptr);//Ищем самый левый элемент правого поддерева нашего узла,для того чтобы заменить им удаляемый узел
strcpy(n->s, tmp->s);
if (n->right == tmp) n->right = tmp->right;//Если самый левый элемент является нашим правым узлом
else FindParent(n, tmp)->left = tmp->right;
tmp->DestructorWithoutSubTree();
}
count--;
}
bool IsEmpty()
{
return !root;
}
void Show(Node* Tree) {
if (Tree == NULL) return;
Show(Tree->left);
printf("\n%s left=%s right=%s",Tree->s,Tree->left->s,Tree->right->s);
Show(Tree->right);
}
void Show() {
Show(root);
printf("\n");
}
void ShowElemAt(size_t i)
{
printf("\n%s\n",(*this)[i]->s);
}
Node *At(Node *p, size_t *n) {
Node *q;
if (p == NULL) return NULL;
q = At(p->left, n);
if (q != NULL) return q;
if ((*n)-- == 0) return p;
return At(p->right, n);
}
Node * operator[](size_t n)
{
size_t *ptr=new size_t;
*ptr = n;
return this->At(root, ptr);
}
};
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
char ch;
char buf[81];
BTree bTree;
do {
system("cls");
printf("\n1. Добавить строку в дерево\n2. Показать элемент с заданным индексом");
printf("\n3. Удалить элемент\n4. Проверить есть ли строка в дереве\n5. Вывести все элементы");
printf("\n6. Очистить дерево\n0. Выход\n");
ch = _getch();
int i;
switch (ch) {
case '1':
printf("\nВведите строку для добавления(80 символов масимум): ");
fflush(stdin);
rewind(stdin);
if(scanf("%80s", buf) != 1)
{
printf("\nОшибка Ввода");
}
else bTree.Insert(buf);
break;
case '2':
printf("\nВведите индекс(индекс первого элемента=0) строки которую хотите получить:");
fflush(stdin);
rewind(stdin);
if(scanf("%d", &i)!=1)
{
printf("\nОшибка Ввода\n");
}
else
{
if(bTree[i])
bTree.ShowElemAt(i);
else printf("\nЭлемент с данным индексом отсуствует в списке!\n");
}
break;
case '3':
printf("\nВведите индекс(индекс первого элемента = 0) строки для удаления: ");
fflush(stdin);
rewind(stdin);
if (scanf("%d", &i) != 1)
{
printf("\nОшибка Ввода\n");
}
else
{
if (bTree[i])
{
bTree.Delete(i);
printf("\nЭлемент удален\n");
}
else printf("\nЭлемент с данным индексом отсуствует в списке!\n");
}
break;
case '4':
printf("\nВведите строку(регистр учитывается): ");
fflush(stdin);
rewind(stdin);
if (scanf("%80s", buf) != 1)
{
printf("\nОшибка Ввода");
}
else
{
if (bTree.Search(buf)) printf("\nСтрока присутствует в дереве\n");
else printf("\nСтрока отсуствует в дереве!\n");
}
break;
case '5':
if (!bTree.IsEmpty()) bTree.Show();
else printf("\nДерево пусто\n");
break;
case '6':
bTree.~BTree();
printf("\nСписок очищен\n");
break;
case '0':
return 0;
default:
printf("\nНеизвестная команда,попробуйте еще раз.\n");
break;
}
system("pause");
} while (1);
system("PAUSE");
return 0;
}