Теоретические сведения
Бинарное (двоичное) дерево (binary tree) - это упорядоченное дерево, каждая вершина которого имеет не более двух поддеревьев, причем для каждого узла выполняется правило: в левом поддереве содержатся только ключи, имеющие значения, меньшие, чем значение данного узла, а в правом поддереве содержатся только ключи, имеющие значения, большие, чем значение данного узла.
Бинарное дерево является рекурсивной структурой, поскольку каждое его поддерево само является бинарным деревом и, следовательно, каждый его узел в свою очередь является корнем дерева.
Узел дерева, не имеющий потомков, называется листом.
Схематичное изображение бинарного дерева
Бинарное дерево может представлять собой пустое множество.
Бинарное дерево может выродиться в списо
#include <conio.h>
#include <iostream.h>
//обход, двоичное/бинарное дерево поиска в ширину используя очередь
//структура элемента дерева
typedef struct tagTREE
{ int inf;
tagTREE *left;
tagTREE *right;
}TREE;
//структура элемента очереди
typedef struct tagQUEUE
{ TREE *tr;
tagQUEUE *next;
}QUEUE;
QUEUE *q;
//функция уничтожения очереди
void DestroyQueue()
{ QUEUE *prev;
if (q != NULL)
{ prev = q;
while(q->next != NULL)
{ q = q->next;
delete prev;
prev = q;
}
delete prev;
}
}
//функция добавления элемента в очередь
void Put(TREE *a)
{ QUEUE *n, *prev;
prev = q;
n = new QUEUE;
n->tr = a;
n->next = NULL;
if (q != NULL)
{ while(prev->next != NULL)
prev = prev->next;
prev->next = n;
}
else
q = n;
}
//функция удаления элемента из очередь
TREE* Get()
{ QUEUE *prev;
TREE *a;
if (q != NULL)
{ prev = q;
a = q->tr;
if (q->next != NULL)
q = q->next;
else
q = NULL;
delete prev;
return a;
}
else
return NULL;
}
//функция проверки на пустоту очереди
int IsEmpty(QUEUE *q)
{ if (q == NULL) return 1;
else return NULL;
}
//-----------------------------------------------
//функция добавления элемента в дерево
TREE* Insert(TREE *root, int x)
{ if (root == NULL)
{ root = new TREE;
root->inf = x;
root->left = root->right = NULL;
}
else
{ if (x <= root->inf)
root->left = Insert(root->left, x);
else
root->right = Insert(root->right, x);
}
return root;
}
//функция удаления элемента из дерева
TREE* Remove(TREE *root, int x)
{ TREE *t;
if (root == NULL) return 0;
if (x == root->inf)
{ if (root->left == NULL)
{ t = root->right;
delete root;
return t;
}
t = root->left;
while(t->right) t = t->right;
t->right = root->right;
return root->left;
}
if (x <= root->inf)
root->left = Remove(root->left, x);
else
root->right = Remove(root->right, x);
return root;
}
//функция вывода дерева на экран
//обходя дерево в ширину
void ShowTree(TREE *root)
{ q = NULL;
TREE *t;
Put(root);
while(!IsEmpty(q))
{ t = Get();
if (t->left != NULL)
Put(t->left);
if (t->right != NULL)
Put(t->right);
cout<<t->inf<<" ";
}
cout<<endl;
}
//обход, двоичное/бинарное дерево поиска в ширину используя очередь
//функция удаления всего дерева
TREE* DestroyTree(TREE *root)
{ if (root)
{ if (root->left != NULL)
root->left = DestroyTree(root->left);
if (root->right != NULL)
root->right = DestroyTree(root->right);
delete root;
}
return NULL;
}
//главная функция
void main(void)
{ TREE *mytree = NULL; //указатель на дерево
int i, mas[10] = {5, 34, 8, 10, 15, 1, 0, 21, -5, 100};
clrscr(); //очищаем экран
//добавляем элементы в дерево
for (i = 0; i<10; i++)
mytree = Insert(mytree, mas[i]);
cout<<"Дерево:"<<endl;
ShowTree(mytree); //выводим дерево
//удаляем элементы
mytree = Remove(mytree, 1);
mytree = Remove(mytree, -5);
cout<<"Дерево после удаления элементов 1 и -5:"<<endl;
ShowTree(mytree); //выводим дерево
}