NetNado
  Найти на сайте:

Учащимся

Учителям



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



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

  • Всякое непустое двоичное T-дерево разбивается на 3 части: корень, левое и правое поддеревья. Отсюда можно дать следующее рекурсивное определение двоичного дерева:

  • пустое дерево – двоичное дерево;

  • вершина с левым и правым двоичными поддеревьями – двоичное дерево.


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

  • PTree = ^TTree;

  • TTree = record

  • Item: T; {элемент дерева}

  • Left, Right: PTree; {указатели на поддеревья}

  • end;



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

  • Двоичное T-дерево упорядочено, если для любой вершины X справедливо свойство:

  • все элементы, хранимые в левом поддереве, меньше элемента, хранимого в X,

  • а все элементы, хранимые в правом поддереве, больше элемента, хранимого в X.



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

  • function Exist(Item: T; Tree: PTree): Boolean;

  • begin

  • if Tree=nil then

  • begin

  • Exist := False;

  • Exit

  • end;



Поиск

  • if Tree^.Item=Item

  • then Exist := True

  • else if Tree^.Item>Item

  • then Exist := Exist(Item, Tree^.Left)

  • else Exist := Exist(Item, Tree^.Right);

  • end;



Бинарные деревья:добавление

  • procedure Add(Item: T; Tree: PTree); Var NewNode: PTree;

  • begin {поиск вершины}

  • while ((Item>Tree^.Item)and(Tree^.Right<>nil))or ((Itemand

  • (Tree^.Left<>nil)) do

  • if Item>Tree^.Item

  • then Tree := Tree^.Right

  • else Tree := Tree^.Left;



Бинарные деревья:добавление

  • {создание и добавление новой вершины}

  • NewNode := New (PTree); NewNode^.Item := Item;

  • NewNode^.Left := nil;

  • NewNode^.Right := nil;

  • If Item>Tree^.Item

  • then Tree^.Right := NewNode

  • else Tree^.Left := NewNode;

  • end;



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

  • public class Tree {

  • / / Определение класса узла дерева

  • public static class Node {

  • public Object item; // содержимое узла

  • public Node left = null; // указатель на левое поддерево

  • public Node right = null; //указатель на правое

  • //поддерево

  • / / Конструкторы узла дерева:

  • / / конструктор листа

  • public Node(Object item) {

  • this.item = item;

  • }



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

  • // Конструктор промежуточного узла

  • public Node (Object item, Node left, Node right) {

  • this.item = item;

  • this.left = left;

  • this.right = right;

  • }

  • }

  • Node root = null; // корень дерева

  • }



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

  • Рекурсивную природу дерева, отраженную в его определении, можно выразить

  • более явно и в описании класса, если в описании ссылок на поддеревья

  • вместо класса Node использовать описатель Tree.



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

  • Высота бинарного

  • дерева может быть выражена следующей формулой:



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

  • public class Tree {

  • private Object item;

  • private Tree left = null;

  • private Tree right = null;

  • public int height () {

  • int hi = (left == null ? 0 : left.height ( ) );

  • int hr = (right == null ? 0 : right.height());

  • return Math.max(hi, hr) + 1 ;

  • }

  • }



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

  • public int height ( ) {

  • return height(root);

  • }

  • private int height(Node n) {

  • if (n == null) {

  • return 0;

  • }

  • else {

  • return Math.max(height(n.left), height(n.right)) + 1;

  • }

  • }



Бинарные деревья (создание/вставка)

  • Алгоритм:

  • Если дерево пусто, заменить его на дерево с одним корневым узлом ((K,V), nil, nil) и остановиться.

  • Иначе сравнить K с ключом корневого узла X.

    • Если K>=X, рекурсивно добавить (K,V) в правое поддерево Т.
    • Если K


Бинарные деревья (создание/вставка)

  • class Tree {

  • public Tree left; // левое и правое поддеревья и ключ

  • public Tree right;

  • public int key;

  • public Tree (int k) { // конструктор с //инициализацией ключа

  • key = k;

  • }



Бинарные деревья (создание/вставка)

  • // insert (добавление нового поддерева (ключа))

  • public void insert( Tree aTree) {

  • if ( aTree.key < key )

  • if ( left != null ) left.insert( aTree );

  • else left = aTree;

  • else if ( right != null ) right.insert( aTree );

  • else right = aTree;

  • }



Бинарные деревья ( вставка в корень)



Бинарные деревья (удаление)

  • Алгоритм:

  • Если дерево T пусто, остановиться

  • Иначе сравнить K с ключом X корневого узла n.

    • Если K>X, рекурсивно удалить K из правого поддерева Т.
    • Если K


Бинарные деревья (удаление)

  • Если K=X, то необходимо рассмотреть три случая.

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


Бинарные деревья (удаление)

  • Если оба поддерева присутствуют, то

        • найдём узел m, являющийся самым левым узлом правого поддерева;
        • скопируем значения полей (key, value) узла m в соответствующие поля узла n.
        • у родителя узла m заменим ссылку на узел m ссылкой на правого потомка m (который, в принципе, может быть равен nil).
        • освободим память, занимаемую узлом m (на него теперь никто не указывает, а его данные были перенесены в узел n).


Бинарные деревья (удаление)



Деревья оптимального поиска

  • Довольно часто встречаются ситуации, когда есть информация о вероятностях обращения к отдельным ключам.

  • Обычно для таких ситуаций характерно «постоянство» ключей, т.е. в дерево поиска не включаются новые ключи и не исключаются старые, структура дерева остается неизменной.

  • сканер транслятора

  • электронные словари

  • системы распознавания текста и тп



Деревья оптимального поиска

  • Предположим, что в дереве поиска вероятность обращения к вершине i равна pi

  • Σ pi = 1, i=1,…,n

  • Требуется так организовать дерево поиска, чтобы общее число шагов поиска, подсчитанное для достаточно большого числа обращений, было минимальным.



Деревья оптимального поиска

  • Тогда (внутренняя) взвешенная длина пути представляет собой сумму всех путей от корня к каждой из вершин, умноженных на вероятность обращения к этой вершине:

  • p= Σ pi *hi, i=1,…,n

  • где hi — уровень вершины i

  • Конечная цель - минимизировать при заданном распределении вероятностей взвешенную длину пути.



Деревья оптимального поиска

  • p1 = 1/7, p2 = 2/7 и р3 = 4/7

  • Взвешенные длины путей деревьев:

  • Р(a)= 11/7, Р(b)=12/7, Р(с) = 12/7, Р(d) = 15/7

  • Р(е) =17/7



Деревья оптимального поиска



Деревья оптимального поиска

  • Сформулируем задачу следующим образом. Даны 2n + 1 вероятностей p1,p2, ,рп и q0,q1,...,qn, где

  • pi — вероятность того, что аргументом поиска является Ki

  • qi — вероятность того, что аргумент поиска лежит между Ki и Ki+1.

  • ( q0 представляет собой вероятность того, что аргумент поиска меньше, чем К1, a qn — вероятность того, что аргумент поиска больше, чем Кп.) Таким образом,

  • p1+p2… +.. рп + q0+ q1 +... + qn = 1



Деревья оптимального поиска

  • A = {a1, a2,…an} – множество элементов, ключи которых упорядочены – K1< K2 <…< Kn

  • B = {b0, b1, ...bn} – множество элементов, ключи Х которых находятся в интервале Ki < X < Ki+1

  • для b0: X< K1, для bn: X > Kn

  • Дерево бинарного поиска с n+1 листьями,

  • представляющими элементы множества B,

  • называется расширенным деревом бинарного

  • поиска



Деревья оптимального поиска

  • нужно найти бинарное дерево, минимизирующее ожидаемое количество сравнений при поиске, а именно



Деревья оптимального поиска

  • Например, ожидаемое количество сравнений для дерева

  • равно 2q0+ 2p1+3q1+3p2 +3q2+р3+q3



Деревья оптимального поиска

  • это значение называется ценой дерева,

  • а дерево с минимальной ценой — оптимальным. При таком определении требование, чтобы сумма всех р и q была равна 1, излишне —

  • мы можем искать дерево с минимальной ценой с любой данной последовательностью весов (p1,..., рn; q0, …, qn)



Деревья оптимального поиска

  • p1=0,2, p2= 0,2, p3= 0,1,p4=0,1

  • q0=0,1, q1=0,1, q2=0,05, q3=0,05, q4=0,1

  • стоимость дерева = 2,05 стоимость дерева = 2,4



Деревья оптимального поиска

  • Оптимальные деревья обладают одним важным свойством, которое помогает их обнаруживать: все их поддеревья тоже оптимальны;

  • любое улучшение поддерева должно приводить к улучшению дерева в целом

  • (схема метода динамического программирования)



Деревья оптимального поиска

  • Пусть c(i,j) — цена оптимального поддерева T(i,j) с весами (pi+1,...,pj, qi,…,qj)

  • и пусть

  • w(i,j) = pi+1 + … + pj +qi+qj — сумма этих весов (0<=i<=j<=n)

  • Поскольку минимально возможная цена дерева с корнем (k) равна

  • w(i,j) + c(i, k-1) + c(k,j),

  • получим



Деревья оптимального поиска

  • Через R(i,j) при i < j обозначим множество всех k, для которых достигается этот минимум это множество определяет корни оптимальных поддеревьев.



Деревья оптимального поиска

  • Пусть T(i,j) для 0<=i

  • для {qi,pi+1,qi+1,…pj,qj}

  • Пусть r(i,j) корень T(i,j)

  • T(i,i) будет дерево состоящее из листа bi и

  • c(i,i) = 0, w(i,j) = qi

  • цена: w(i,j) + c(i, k-1) + c(k,j),



Деревья оптимального поиска

  • Алгоритм поиска оптимальных бинарных деревьев поиска).

  • Даны 2n+1 неотрицательных веса (p1,... ,рп; q0,... qn). Алгоритм строит бинарные деревья t(i,j), имеющие минимальную цену для весов (pi+1,. ..,pj, qi,..., qj). Вычисляются три массива, а именно

  • c[i,j], 0<=i<=j<=n, цена t(i,j),

  • r[i,j], 0<=iкорень t(i,j);

  • w[i,j], 0 <= i <= j <= n, общий вес t(i,j).



Деревья оптимального поиска

  • Результаты работы алгоритма определяются массивом r:

  • при i = j t(i,j) пуст;

  • в противном случае левое поддерево —

  • t(i, r[i,j]-1),

  • а правое поддерево — t(r[i,j], j).



Деревья оптимального поиска

  • Алгоритм Гильберта-Мура

  • Инициализация:даны p1,p2,..,pn и q0,q1,…qn. Для i=0,1,2,…n положить wij=qi, cii=0, rii=bi

  • Для l= 1,2,…n выполнить шаг 3

  • Для i=0,1,2,…n-l выполнить шаг 4

  • Положить j=i+l, wij=wij-1+pi+qj

  • Пусть m – значение k (i

  • Положить cij=wij + cim-1 +cmj; rij= am



Деревья оптимального поиска

  • Вычислив r(i,j) строим дерево T(0,n)

  • r(0,n)- корень дерева, если r(0,n)=ak, то левый сын - r(0,к-1), а правый r(к,n)

  • Если am=rij, то у am левый сын - r(i,m-1), а правый - r(m,j),

  • пример



Деревья оптимального поиска

  • С помощью уравнений можно вычислить c(i,j) для j —i= 1,2,..., n;

  • имеется примерно 1/2n2 таких значений, а операция минимизации выполняется примерно для 1/6 n3 значений k.

  • те можно определить оптимальное дерево за O(n3) единиц времени с использованием О(п2) ячеек памяти.

  • частоты баланс оптим



АВЛ- деревья

  • Г.М.Адельсон -Вельский и Е.М.Ландис (1962).

  • АВЛ-деревья или сбалансированные деревья.

  • Высотой поддерева будем считать максимальную длину цепи y[1]..y[n] его вершин такую, что y[i+1] – сын y[i] для всех i.

  • Высота пустого дерева равна 0. Высота дерева из одного корня – единице.



АВЛ- деревья

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



АВЛ- деревья

  • Дерево считается сбалансированным по АВЛ (в дальнейшем просто «сбалансированным»), если для каждой вершины выполняется требование: высота левого и правого поддеревьев различаются не более, чем на 1.

  • Не всякое сбалансированное дерево идеально сбалансировано, но всякое идеально сбалансированное дерево сбалансировано.



АВЛ- деревья

  • Любая из следующих операций может быть выполнена за t ~ log N:

  • поиск элемента по заданному ключу;

  • поиск k-го элемента по заданному k;

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

  • место;

  • удаление определенного элемента.



АВЛ- деревья



АВЛ- деревья

  • PTree = ^TTree;

  • TTree = record

  • Item: T; {элемент дерева}

  • Left, Right: PTree;

  • {указатели на поддеревья}

  • Balance: ShortInt;

  • {показатель сбалансированности}

  • end;



АВЛ- деревья

  • возможный вариант представления на С++ или Java

  • struct node

  • { int Key;

  • int Count;

  • int bal; // Показатель

  • //балансированности вершины.

  • node *Left;

  • node *Right;

  • };



АВЛ- деревья

  • Включение вершины

  • hL = hR. После включения L и R станут разной высоты, но критерий сбалансированности не будет нарушен;

  • hL < hR. После включения L и R станут равной высоты, то есть критерий сбалансированности даже улучшится;

  • hL > hR. После включения критерий сбалансированности нарушится и дерево необходимо перестраивать.



АВЛ- деревья

  • Например:



АВЛ- деревья

  • Алгоритм включения вершины в дерево:

  • проход по дереву, чтобы убедиться, что включаемого значения в дереве нет;

  • включение новой вершины и определение результирующего показателя сбалансированности;

  • "отступление" по пути поиска и проверка в каждой вершине показателя сбалансированности. При необходимости - балансировка.



АВЛ- деревья

  • Алгоритм включения вершины в дерево:

  • проход по дереву, чтобы убедиться, что включаемого значения в дереве нет;

  • включение новой вершины и определение результирующего показателя сбалансированности;

  • "отступление" по пути поиска и проверка в каждой вершине показателя сбалансированности. При необходимости - балансировка.



АВЛ- деревья



АВЛ- деревья

  • Однократный LL-поворот

  • Однократный RR-поворот

  • Двухкратный LR-поворот

  • Двухкратный RL-поворот

  • Построение АВЛ-дерева



АВЛ- деревья



АВЛ- деревья



АВЛ- деревья



АВЛ- деревья

  • Математическое ожидание значения высоты при больших n близко к значению h = log2n + c, где c - малая константа (c ~0.25).

  • Вероятность того, что при вставке не потребуется дополнительная балансировка, потребуется однократный поворот или двукратный поворот, близка к значениям 2/3, 1/6 и 1/6

  • Среднее число сравнений при вставке n-го ключа в дерево выражается формулой alog2n+b (a и b - постоянные).

  • Для АВЛ-дерево операции: поиск, вставка и удаление вершины с заданным ключом имеет временную сложность O(log2n).



2-3-деревья

  • определение 2-3-дерева:

  • Каждый узел 2-3-дерева содержит одно или два значения.

  • Узлы дерева делятся на две категории — листья и промежуточные (внутренние) узлы, причем если промежуточный узел содержит одно значение, то он имеет два непустых поддерева (2-узел), а если он содержит два значения, то он имеет три непустых поддерева (3-узел).

  • Принцип упорядоченности значений сохраняется для 2-3-дерева . Для 2-узла, как и в случае бинарного дерева поиска, все значения, лежащие в левом поддереве, имеют значения, меньшие значения, хранящегося в узле, а значения, лежащие в правом поддереве, — больше или равны значениям, хранящимся в узле.



2-3-деревья

  • Для 3-узла упорядоченность означает следующее: если ключи, хранящиеся в нем, имеют значения K1, K2, а поддеревья этого узла обозначены T1, T2 и T3, то справедливо

  • неравенство

  • T1 < K1 < Т2 < К2 < Т3

  • • Все листья лежат на одном и том же уровне.



2-3-деревья



2-3-деревья



2-3-деревья

  • представление в виде бинарного дерева

  • Вставка и удаление



Красно-чёрные деревья (Red-Black Tree, RB-Tree)

  • Свойства КЧД

  • Корень черный;

  • Каждая вершина может быть либо красной, либо чёрной. Бесцветных вершин, или вершин другого цвета быть не может.

  • Каждый лист (NIL) имеет чёрный цвет.

  • Если вершина красная, то оба её потомка – чёрные.

  • Все пути от корня к листьям содержат одинаковое число чёрных вершин.



Красно-чёрные деревья (Red-Black Tree, RB-Tree)

  • соответствие 2-3 и 2-4 дерева и КЧД



Красно-чёрные деревья (Red-Black Tree, RB-Tree)



Красно-чёрные деревья (Red-Black Tree, RB-Tree)

  • Операции вставки и удаления вершин в КЧД могут нарушать свойства КЧД.

  • Чтобы восстановить эти свойства, надо будет перекрашивать некоторые вершины и менять структуру дерева



Красно-чёрные деревья (Red-Black Tree, RB-Tree)

  • Вставка



Красно-чёрные деревья (Red-Black Tree, RB-Tree)

  • Вставка



Красно-чёрные деревья (Red-Black Tree, RB-Tree)

  • Создание дерева



Красно-чёрные деревья (Red-Black Tree, RB-Tree)

  • Ввод объекта «ключ-элемент» в красно-черное дерево, хранящее n элементов, выполняется за О(log n) времени и требует

  • максимум O(log n) перекрашиваний

  • http://rain.ifmo.ru/cat/view.php/vis/trees



Сильноветвящиеся деревья



B- деревья (B-trees, R.Bayer)



B- деревья (B-trees)

  • каждый узел имеет не более NumberOfItems сыновей;

  • каждый узел, кроме корня, имеет не менее NumberOfItems/2 сыновей;

  • корень, если он не лист, имеет не менее 2-х сыновей;

  • все листья расположены на одном уровне (дерево сбалансировано);

  • нелистовой узел с k сыновьями содержит не менее k-1 ключ.



B- деревья (B-trees)

  • Узел B-дерева, содержащий j ключей и j+1 указатель

  • K1< K2< ….

  • Pi указывает на поддерево с ключами между Ki и Ki+1



B- деревья (B-trees)

  • Type PBTreeNode = ^TBTreeNode; TBTreeNode =

  • record {узел дерева}

  • Count: Integer;

  • PreviousNode: PBTreeNode;

  • Items: array[0..NumberOfItems ] of record

  • Value: ItemType;

  • NextNode: PBTreeNode;

  • end;

  • end;



B- деревья (B-trees)



B- деревья (B-trees)

  • типичный шаблон работы с объектом х B- дерева :

  • х ← указатель на некоторый объект

  • Disk_Read(x)

  • Операции, обращающиеся и/или изменяющие поля х

  • Disk_Write(x) // Не требуется, если

  • поля х не изменялись

  • Прочие операции, не изменяющие поля х



B- деревья (B-trees)

  • 1. Каждый узел x содержит следующие поля:

  • а) п (х), количество ключей, хранящихся в данный момент в узле х,

  • б) Собственно ключи, количество которых равно п (х) и которые хранятся в невозрастающем порядке

  • key1 (х) key2 (х) • • • ≤ key п (х) (х)

  • в)Логическое значение leaf (х), равное true, если х является листом, и false, если х — внутренний узел.



B- деревья (B-trees)

  • Кроме того, каждый внутренний узел х содержит п (х)+1 указателей

  • с1 (х), с2 (х), … с п (х)+1 (х)

  • на дочерние узлы. Листья не имеют дочерних узлов.



B- деревья (B-trees)

  • Ключи keyi (х)разделяют поддиапазоны ключей, хранящихся в поддеревьях: если ki — произвольный ключ, хранящийся в поддереве с корнем сi(х) то k1 key1 (х) k2 ≤ key2 (х) …≤

  • keyn(х) (х) k n(х)+1



B- деревья (B-trees)

  • Все листья расположены на одной и той же глубине, которая равна высоте дерева h.

  • Имеются нижняя и верхняя границы количества ключей, которые могут содержаться в узле.

  • Эти границы могут быть выражены с помощью одного фиксированного целого числа t ≥ 2, называемого минимальной степенью (minimum degree) В-дерева:



B- деревья (B-trees)

  • Каждый узел, кроме корневого, должен содержать как минимум t - 1 ключей.

  • Каждый внутренний узел, не являющийся корневым, имеет,таким образом, как минимум t дочерних узлов.

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

  • Каждый узел содержит не более 2t — 1 ключей. Таким образом, внутренний узел имеет не более 2t дочерних узлов. Узел заполнен (full), если он содержит ровно

  • 2t — 1 ключей.



B- деревья (B-trees)

  • Высота В-дерева с n≥1 узлами и степенью t ≥ 2 не превышает

  • log t (n+1)/2



B- деревья (B-trees)

  • Алгоритм поиска:

  • BTreeSearch (x, k);

  • i:=1;

  • While i≤ п (х) & k > keyi(x)

  • i:= i +1;

  • If i≤ п (х) & k = keyi(x)

  • then return (x,i);

  • If leaf (x)

  • then return null

  • else DiskRead(ci(х)); return

  • BTreeSearch (сi (х), k);



B- деревья (B-trees)

  • Количество дисковых страниц, к которым обращается BTreeSearch

  • O (h) = O (logt n)

  • Общее время вычислений

  • O (t*h) = O (t*logt n)



B- деревья: поиск



B- деревья: создание пустого дерева

  • BTreeCreate( );

  • x :=AllocateNode ( );

  • leaf(x) := true;

  • n(х) := 0;

  • DiskWrite (x);

  • root := x



B- деревья: добавление

  • Поиск листового узла Node, в который следует произвести добавление элемента Item.

  • Добавление элемента Item в узел Node.

  • Если Node содержит больше, чем NumberOfItems элементов (произошло переполнение), то

  • делим Node на две части, не включая в них средний элемент;

  • Item=средний элемент Node;

  • Node=Node.PreviousNode;

  • Переходим к пункту 2.



B- деревья: добавление



B- деревья: добавление



B- деревья: добавление

  • BTreeInsert(T,k);

  • r:= root(T);

  • if n(r) = 2t-1;

  • then s:= AllocateNode ( );

  • root(T) :=s;

  • leaf (s) := false;

  • п (s) :=0;

  • c1(s) :=r;

  • BTreeSplitChild(s,1,r);

  • BtreeInsertNonfull(s,k);

  • else BtreeInsertNonfull(r,k);



B- деревья: добавление



B- деревья: добавление



B- деревья: добавление



B- деревья: добавление



B- деревья: добавление



B- деревья: удаление

  • Если узeл k находится в узле x и x –лист удаляем k из x

  • Если узeл k находится в узле x и x –внутренний узел

  • Если дочерний по отношению к x узел у, предшествующий ключу k, содержит не менее t ключей, то находим k1 – предшественника k в поддереве, корнем которого является y,рекурсивно удаляем k1 и заменяем k на k1



B- деревья: удаление

  • Если дочерний по отношению к x узел z, следующий за ключом k, содержит не менее t ключей, то находим k1 – следующий за k в поддереве, корнем которого является z, рекурсивно удаляем k1 и заменяем k на k1



B- деревья: удаление

  • если у и z содержат по t-1 ключей, то осуществляется слияние z в y

  • из x удаляется k и ссылка на z, y содержит 2t-1 узел



B- деревья: удаление



B- деревья: удаление



B- деревья: удаление



B- деревья: удаление



B- деревья: удаление



страница 1


скачать

Другие похожие работы:


Контрольная работа №10 № Решите задачу

Контрольная работа: 1 стр.



Документы

архив: 1 стр.