Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по прогр.ч.2.doc
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
293.89 Кб
Скачать

Лекция 12

Бинарные деревья поиска

Бинарные деревья поиска (БДП) часто используются для представления данных, среди которых идет поиск элемента по ключу.

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

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

Предположим, что имеется описание класса, характеризующего БДП:

class bdp

{public:

int b;

char name[20];

bdp *left;

bdp*right;

void create_tree();//создание БДП

void output_tree(bdp *p);//вывод на экран БДП

void search(int key,bdp *p);//поиск элемента в БДП

void insert(bdp obj,bdp *&p);//вставка элемента в БДП

void delete_element(int key,bdp *&p);//удаление элемента из БДП

void delete_tree(bdp *&p);//удаление БДП из памяти компьютера

};

Предположим, что имеются следующие описания:

bdp *head;//указатель на корень дерева

bdp *q;//текущий указатель

Поиск элемента с заданным ключом в БДП

void bdp::search(int key,bdp *p)

{/*функция выводит на экран информационные поля найденного элемента или сообщает, что элемент не найден*/

while(p!=NULL&&p->b!=key)

{if(p->b<key)

p=p->right;

else

p=p->left;

}

if(p==NULL)

cout<<"\nЭлемент не найден";

else

{cout<<"\n------------------------";

cout<<"\n|nomer|name|";

cout<<"\n------------------------";

cout<<"\n"<<setw(6)<<p->b;

cout<<"|"<<setw(10)<<p->name<<"|";

cout<<"\n------------------------\n";

}

getch();

}

Включение элемента с заданным ключом в БДП

void bdp::insert(bdp obj,bdp *&p)

{if(p==NULL)

{p=new bdp;

p->b=obj.b;

strcpy(p->name,obj.name);

p->left=NULL;

p->right=NULL;

}

else

if(obj.b<p->b)

insert(obj,p->left);

else

if(obj.b>p->b)

insert(obj,p->right);

}

Исключение элемента с заданным ключом из БДП

Исключение элемента реализуется просто, если вершина является листом, либо вершиной с одним потомком. Для удаления листа или вершины с одним потомком достаточно скорректироватьссылку у предшествующей вершины. Основная трудность состоит в удалении вершины с двумя потомками. В этом случае нужно найти подходящую вершину, которую можно было бы вставить на место удаляемой. Такой элемент всегда существует: это либо самый правый элемент левого поддерева, либо самый левый элемент правого поддерева.

Алгоритм удаления элемента из БДП должен различать 3 случая:

1.элемента с заданным ключом в дереве нет;

2.элемент с заданным ключом имеет не более одной ветви;

3.элемент с заданным ключом имеет две ветви.

Определим функцию del() , которая заменяет удаляемый элемент с адресом q на самый правый элемент левого поддерева удаляемого элемента, если удаляемый элемент имеет две ветви.

void del(bdp *&r)

{

if(r->right==NULL)

{q->b=r->b;

strcpy(q->name,r->name);

q=r;

r=r->left;

}

else del(r->right);

}

void bdp::delete_element(int key,bdp *&p)

{

if(p==NULL)

cout<<"\nЭлемента нет";

else

if(key<p->b)

delete_element(key,p->left);

else

if(key>p->b)

delete_element(key,p->right);

else

{q=p;

if(q->right==NULL)

p=q->left;

else

if(p->left==NULL)

p=q->right;

else del(q->left);

delete q;

}

}

Вывод значений ключей элементов дерева по возрастанию

void bdp::output_tree(bdp *p)

{if(p!=NULL)

{output_tree(p->left);

cout<<"\n|"<<setw(6)<<p->b;

cout<<"|"<<setw(10)<<p->name;

cout<<"|";

output_tree(p->right);

}

}

Удаление БДП из динамической памяти

void bdp::delete_tree(bdp *&p)

{if(p!=NULL)

{delete_tree(p->left);

delete_tree(p->right);

delete p; p=NULL;

}

}

Создание БДП

void bdp::create_tree()

{int i;

bdp obj;

head=NULL;

for(i=0;i<n;i++)//n – количество вершин в дереве

{cin>>obj.b;

gets(obj.name);

insert(obj,head);

}

}