Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
algorithms-2010.doc
Скачиваний:
33
Добавлен:
06.12.2018
Размер:
9.83 Mб
Скачать

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

Бинарными деревьями называют деревья, в которых, как правило, задан корневой элемент или корень и для каждой вершины существует не более двух потомков. Например, для задания одной вершины бинарного дерева целых чисел в языке С можно использовать следующую структуру

typedef struct STree_

{

int value;

struct STree_ *prev;

struct STree_ *left, *right;

} STree;

здесь указатель prev указывает на родительский элемент данной вершины, а left и right – на двух потомков, которых традиционно называют левым и правым. Величина value называется ключом вершины.

Бинарное дерево называется деревом поиска, если для любой вершины дерева a ключи всех вершин в правом поддереве больше или равны ключа a, а в левом – меньше. Неравенства можно заменить на строгие, если известно, что в дереве нет равных элементов.

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

STree *a;

Отсутствие потомка обозначается нулевым значением соответствующего указателя.

Часто, если это не будет приводить к двусмысленностям, под сравнением элементов мы будем подразумевать сравнение соответствующих ключей.

Ветвью дерева называется последовательность вершин дерева, каждый последующий элемент в которой является потомком предыдущего.

Длиной ветви дерева называется количество элементов в ветви.

Высотой дерева называется максимальная длина всех ветвей дерева.

Основные операции, которые можно совершать с бинарными деревьями:

  • поиск элемента в дереве (т.е. элемента с ключом, равным заданному)

  • добавление элемента в дерево

  • удаление элемента из дерева

  • поиск минимального и максимального элемента в дереве

  • если рассмотреть дерево поиска, как упорядоченную по возрастанию последовательность элементов, то: для текущего элемента поиск следующего/предыдущего

  • для данной вершины дерева v разбиение дерева поиска T на два дерева поиска T1 и T2 таких, что все элементы в T1 меньше или равны v, и все элементы в T2 больше или равны v

  • для двух деревьев поиска T1 и T2 таких, что все элементы в T1 меньше или равны всех элементов в T2 (будем далее для таких деревьев говорить, что дерево T1 меньше или равно дерева T2: T1 T2): слияние деревьев в одно дерево поиска T

Покажем, что все эти операции можно совершить за время O(h), где h – высота рассматриваемого дерева.

Поиск элемента в дереве

Требуется найти элемент, равный v, в дереве. Введем понятие текущей вершины дерева c. Сначала в качестве c выберем корень дерева. Рекурсивно вызывается следующая процедура:

Если c==NULL то ИСКОМЫЙ ЭЛЕМЕНТ В ДЕРЕВЕ НЕ СОДЕРЖИТСЯ

Если v==c то return c

Если vc то выполнить эту же процедуру для c->right

иначе выполнить эту же процедуру для c->left

На языке С это будет выглядеть следующим образом

STree *Find(STree *root, int v)

{

if(root==NULL)return NULL;

if(root->value==v)return root;

if(root->value>=v)return Find(root->right,v);

else return Find(root->left,v);

}

или более коротко:

STree *Find(STree *root, int v)

{

return root==NULL?NULL: root->value==v? root: v>=root->value?

Find(root->right,v): Find(root->left,v);

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]