Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Динамические структуры данных1 - копия.doc
Скачиваний:
2
Добавлен:
31.07.2019
Размер:
79.87 Кб
Скачать

Бинарные деревья.

Древовидные иерархические структуры данных широко применяются при классификации различных объектов (например, в биологии). Есть корень дерева, который ссылается на нескольких своих потомков (основных ветвей), те в свою очередь ссылаются на своих потомков (более мелких ветвей) и т.д. Последние потомки ни на кого не ссылаются (они называются листьями). Если у каждого предка не более двух потомков, то дерево называется бинарным.

Каждый узел бинарного дерева удобно хранить в виде следующей структуры

struct Node{

int d;

Node *left;

Node * right;

};

Здесь d – это данное, a left и right – указатели на левое и правое поддерево.

Если бинарное дерево организовано так, что для каждого узла в его левом поддереве все ключи меньше , чем у самого узла, а в правом – больше, то дерево называется деревом поиска.

Привести пример.

Каждое поддерево тоже является деревом, поэтому дерево является рекурсивной структурой данных. Работать с такими данными удобнее всего с помощью рекурсивных алгоритмов.

Пример. Напечатаем дерево.

Печатаем (дерево){

Печатаем (левое поддерево);

Печатаем (корень);

Печатаем (правое поддерево);

}

Для бинарных деревьев должны быть реализованы следующие операции:

  1. Включение узла в дерево

  2. Поиска по дереву

  3. Обхода дерева

  4. Удаления узла.

Для каждой операции можно создать рекурсивный алгоритм или его нерекурсивный аналог.

В качестве примера написаны рекурсивный вариант обхода дерева и нерекурсивный алгоритм поиска вершины с включением.

#include<iostream.h>

struct Node{

int d;

Node *left;

Node * right;

};

Node *first(int d);

Node *search_insert(Node * root,int d);

void print_tree(Node *p,int l);

main(){

int b[]={10,25,20,6,21,8,1,30};

Node *root=first(b[0]);

for(int i=1;i<8;i++){

search_insert(root,b[i]);

}

print_tree(root,0);

return(0);

}

Node *first(int d){

Node *pv=new Node;

pv->d=d;

pv->left = NULL;

pv->right = NULL;

return(pv);

}

Node *search_insert(Node * root, int d){

Node *pv = root;

Node *prev;

int found = 0;

while(pv && !found){

prev = pv;

if( d == pv ->d )

found = 1;

else if( d < pv ->d )

pv = pv -> left;

else

pv = pv -> right;

}

if(found)

return ( pv );

Node *pnew = new Node;

pnew -> d = d;

pnew -> left = NULL;

pnew -> right = NULL;

if( d< prev -> d)

prev -> left = pnew;

else

prev -> right = pnew;

return(pnew);

}

void print_tree( Node *p, int l){

if(p){

print_tree(p->left,l+1);

for(int i=0;i<l;i++)

cout << " ";

cout << p->d << endl;

print_tree(p->right, l+1);

}

}

Упр. Реализовать удаление узла из дерева.

Примечание. Это не очень простая задача. Для узлов, в которых меньше двух ссылок, удаление тривиально. Если в узле две ссылки, то его заменяют на узел с самым близким к нему ключом. Это может быть самый левый узел его правого поддерева или самый правый узел его левого поддерева.

Упр 2. Написать рекурсивный вариант алгоритма поиска вершины с включением.