Вы находитесь на странице: 1из 15

БИНАРНЫЕ

ДЕРЕВЬЯ

Всякое дерево, не приносящее


плода доброго, срубают
и бросают в огонь.
Ев. от Матфея, 19:30

Основы программирования
Содержание
2

 Деревья и бинарные деревья


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

Основы программирования © М.Л. Цымблер


Деревья и бинарные деревья
3

 Дерево – связный ациклический граф.


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

Основы программирования © М.Л. Цымблер


Преобразование дерева в бинарное
дерево
4

1 1. Соединить братьев
каждого уровня.
2. Стереть все
2 3 4 вертикальные связи,
кроме связей каждого
отца к первому сыну.
5 6 7 8

9 10 11 12
Основы программирования © М.Л. Цымблер
Бинарное дерево
5

 <дерево> ::= ( <данное> <лев. поддерево> <прав. поддерево> ) |


<пусто> (m
(e
<лев. поддерево> ::= \n<дерево>
(c
<прав. поддерево> ::= <дерево>\n (a NIL NIL)
NIL )
(g
NIL
(k NIL NIL)
)
)
(s
(p (o NIL NIL) (s NIL NIL) )
(y NIL NIL)
)
)
Основы программирования © М.Л. Цымблер
Бинарное дерево: терминология
6

1  Корень, листья
 Отец, сыновья, братья
2 3  Предок, потомок
 Высота

4 5 6 7

8 9 10
Основы программирования © М.Л. Цымблер
Бинарное дерево поиска
7

 Бинарное дерево поиска – бинарное дерево,


вершины которого подчиняются отношению
порядка и включаются в дерево в
соответствии со следующим правилом:
 Если дерево пустое, то создать дерево, корень
которого хранит значение включаемой вершины.
 Если дерево не пустое, то сравнить значение
включаемой вершины со значением в корне дерева.
 Если значение включаемой вершины меньше значения
в корне, то включить вершину в левое поддерево
(рекурсивно).
 Если значение включаемой вершины больше значения
в корне, то включить вершину в правое поддерево
(рекурсивно).

Основы программирования © М.Л. Цымблер


Создание бинарного дерева
16

t = Tree(Tree("a", "b"), Tree("c", "d")) 1


t.right.left

MakeRoot(1); 2 3
AppendLeft(Root, 2);
AppendRight(Root, 3);
AppendLeft(Root^.Left, 4);
AppendRight(Root^.Left, 5); 4 5 6 7
AppendLeft(Root^.Right, 6);
AppendRight(Root^.Right, 7);
AppendLeft(Root^.Left^.Left, 8);
AppendLeft(Root^.Left^.Right, 9);
8 9 10
AppendRight(Root^.Left^.Right, 10);
Основы программирования
Включение вершины
в бинарное дерево поиска
17

1. НАЧАЛО
2. Если корень пуст, то
1. включить в корень
2. перейти к шагу 5
3. Если значение элемента меньше значения в
корне, то включить вершину в левое поддерево
4. Иначе, включить вершину в правое поддерево
5. СТОП

Бинарные деревья
Поиск вершины
в бинарном дереве поиска
19

1. НАЧАЛО
2. Если корень пуст, то
1. result = «вершина не найдена»
2. перейти к шагу 6
3. Если элемент в корне равен образцу, то
1. result = «вершина найдена»
2. перейти к шагу 6
4. Иначе если значение образца меньше значения в
корне, то найти вершину в левом поддереве
5. Иначе, найти вершину в правом поддереве
6. СТОП

Бинарные деревья
Удаление вершины
из бинарного дерева поиска
20

1. НАЧАЛО
2. Если у вершины нет детей, то
1. удалить вершину
2. перейти к шагу 5
3. Если у вершины один сын (левый или правый), то
1. поместить сына вместо удаляемой вершины в дереве,
2. удалить вершину
3. перейти к шагу 5
4. Если у вершины два сына, то
1. найти в левом поддереве вершину с максимальным значением,
2. поместить ее значение вместо удаляемой вершины,
3. удалить вершину с максимальным значением в левом поддереве
5. СТОП
Бинарные деревья
Обходы бинарного дерева
21

 Прямой
1
 Посетить корень
 Посетить левое поддерево
 Посетить правое поддерево
2 3
 Обратный
 Посетить левое поддерево
 Посетить корень
 Посетить правое поддерево
4 5 6 7
 Концевой
 Посетить левое поддерево
 Посетить правое поддерево
 Посетить корень
8 9 10
Основы программирования
Прямой обход дерева
22

1, 2, 4, 8, 5, 9, 10, 3, 6, 7 1

def PreOrder(self, root): 2 3


if root == None:
return 0
print (root.data)
self.PreOrder(root.left) 4 5 6 7
self.PreOrder(root.right)

8 9 10
Основы программирования
Обратный обход дерева
23

8, 4, 2, 9, 5, 10, 1, 6, 3, 7 1

def PostOrder(self,root): 2 3
if root==None:
return 0
self.PostOrder(root.left)
4 5 6 7
print(root.data)
self.PostOrder(root.right)

8 9 10
Основы программирования
Концевой обход дерева
24

8, 4, 9, 10, 5, 2, 6, 7, 3, 1 1

procedure ReverseOrder(self,root): 2 3
if root==None:
return 0
self.ReverseOrder(root.left)
4 5 6 7
self.ReverseOrder(root.right)
print(root.data)

8 9 10
Основы программирования