Upload
simplepeople
View
109
Download
4
Embed Size (px)
Citation preview
Анализ комбинаторных алгоритмов
Лекция №6Элементарные
структуры данныхЧасть IV
Порядковые деревья
Порядковым называется красно-черное дерево, каждая вершина которого, помимо обычной информации имеет поле в котором хранится размер поддерева (не считая NULL- листьев) с корнем в x (size).
Считая что размер поддерева листа равен 0 можно написать следующее соотношение:x->size = x->left->size + x->right->size +1
Порядковые деревья
114
142
151
24
11
79
52
81
41
void OTSelect(x,i){r = x->left->size+1;if(i==r) return x;else if(i<r) return OTSelect(x->left,i);else return OTSelect(x->right,
i-r);}
Порядковые деревья
void OTRank(root, x){r = x->left->size+1;y = x;while (y!=root){ if(y==y->parent->right); r=r + y->parent->left->size+1; y = y->parent;}return r;
}
Порядковые деревья
Для того чтобы при балансировке дерево продолжало оставаться порядковым в процедуру вращения необходимо и достаточно добавить строки:y->size = x->size;x->size = x->left->size+x->right->size +1;
4219
9312
α
β γ
4211
9319
αβ
γ
Левое вращение
Порядковые деревья
Порядковые деревья позволяют осуществлять операции доступа к элементу по данному индексу и получения индекса по данному элементу за время O(log(n)).
Порядковые деревья хороши для реализации разреженных массивов.
B-Деревья
B-деревом называется корневое дерево в котором Каждая вершина содержит поля хранящие
количество ключей хранящихся в ней(n); сами ключи (с доп. инф.) в неубывающем порядке; булевское значение (leaf), истинное когда вершина
является листом Если x – внутренняя вершина, то она содержит
n+1 указателей на детей.
B-Деревья
Ключи служат границами, разделяющими значения ключей в поддеревьях.
Все листья находятся на одной и той же глубине (равной высоте дерева)
Число ключей в одной вершине ограничено сверху и снизу. Обычно ограничение задают одним числом t. Каждая вершина (кроме листьев) содержит по меньшей мере t-1 ключ, но не более 2t-1 ключей (полная вершина).
B-Деревья
M
Q T XD H
B C F G V WR SN PJ K L Y Z
2-3-4 дерево
B-Деревья
Теорема.Для всякого дерева высотой h и минимальной степени t, хранящего n>1 ключей выполняется неравенство:
21log
nh t
B-Деревья. Основные операции.
void BTreeSearch(x,k){i = 1;while ((i <= x->n)&&(k>x->key[i]))i = i+1;if ((i<=x->n)&&(k==x->key[i]))return (x, i);if (x->leaf) return null;else return BTreeSearch(x->child[i],k);
}
B-Деревья. Основные операции.
// x-неполная, y-полнаяvoid BTreeSplitChild(x, i , y){
z = NewNode(); z ->leaf = y->leaf; z->n = t-1;for (j=1; j<t; j++) z->key[j] = y->key[j+t];if (! y->leaf) for(j=1; j<=t; j++) z->child[j]=y->child[j+t];y->n = t-1;for(j=x->n+1;j>=i+1;j--) x->child[j+1] =x->child[j];x->child[i] = z;for(j=x->n; j>=i; j--) x->key[j+1] = x->key[j];x->key[i]=y->key[t]; x->n = x->n+1;
}
B-Деревья. Основные операции.
… N W …
P Q R S T U V T U V
… N S W …
P Q R
B-Деревья. Основные операции.
void BTreeInsert(root , k){r = root;if (r->n == 2t-1){
s = NewNode();root = s; s->leaf = false;s->n = 0; s->c[1] = r;BTreeSplitChild(s.1.r);BTreeInsertNonFull(s,k);
}else BTreeInsertNonFull(r,k);
}
B-Деревья. Основные операции.void BTreeInsertNonFull(x , k){
i = x->n;if (x->leaf){
while ((i>=1)&&(k<x->key[i])){x->key[i+1] = x->key[i]; i--;}x->key[i+1] = k; x->n = x->n+1; }else{while((i>=1)&&(k<x->key[i])) i--; i++;if(x->child[i]->n == 2*t-1) {BTreeSplitChild(x,i,x->child[i]);if (k>x->key[i]) i--; }BTreeInsertNonFull(x->child[i],k); };
}
B-Деревья. Основные операции.
G M P X
A C D E J K R S T U VN O Y Z
B-Деревья. Основные операции.
G M P X
A B C D E J K R S T U VN O Y Z
B-Деревья. Основные операции.
G M P T X
A B C D E J K Q R SN O Y ZU V
B-Деревья. Основные операции.
G M
A B C D E J K L Q R SN O Y ZU V
P
T X
B-Деревья. Основные операции.
C G M
A B J K L Q R SN O Y ZU V
P
T X
D E F
B-Деревья. Основные операции.
При удалении вершины из B-дерева возможны следующие случаи:
Если k находится в вершине x являющейся листом – удаляем k из x.
B-Деревья. Основные операции.
C G M
A B J K L Q R SN O Y ZU V
P
T X
D E
- F
B-Деревья. Основные операции.
Если k в внутренней вершине x, то: Если ребенок y вершины x, предшествующий k,
содержит не менее t элементов, то находим k`, непосредственно предшествующий k. Он находится в листе поддерева с корнем в y. Удаляем k` (рекурсивный вызов), заменяем ключ k на k`.
Если ребенок z, следующий за k, сдержит не менее t элементов, поступаем аналогично.
Если y и x содержат по t-1 элементов, тогда соединяем y, z и k. Удаляем k (рекурсивный вызов).
B-Деревья. Основные операции.
C G L
A B J K Q R SN O Y ZU V
P
T X
D E
- M
B-Деревья. Основные операции.
C L
A B D E J K Q R SN O Y ZU V
P
T X
- G
B-Деревья. Основные операции.
Если x внутренняя вершина, но k в ней нет, найдем среди ее детей корень поддерева в котором должен лежать искомый ключ. Если корень содержит не менее t детей, то вершину можно удалить рекурсивно, иначе надо предварительно сделать один из дополнительных шагов.
B-Деревья. Основные операции.
Если вершина (корень поддерева) содержит t-1 элемент, но один из ее соседей (ближних братьев) содержит t элементов, тогда добавим в вершину элемент вершины x разделяющий соседей, а в вершину x поместим самый правый(левый) элемент соседа.
Если оба соседа содержат t-1 элементов, тогда объединим вершину с одним из соседей.
B-Деревья. Основные операции.
C L P T X
A B E J K Q R SN O Y ZU V
- D
B-Деревья. Основные операции.
C L P T X
A E J K Q R SN O Y ZU V
- B