Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / Struktury.docx
Скачиваний:
37
Добавлен:
04.04.2018
Размер:
2.84 Mб
Скачать

Исключение из балансированного дерева (авл)

Балансировки остаются такими же (однократные и двукратные повороты). Простые случаи - удаление листовой вершины или вершины с одним потомком. Если от исключаемой вершины отходят 2 поддерева, то она заменяется на самую правую вершину ее левого поддерева.

Б – деревья. Это сильно ветвящиеся деревья, т.е. у каждой вершины сколько угодно потомков.

Type ptr=^person; person=record name:string; child,next:ptr; end;

Peter



John

next

child

nill

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

Предполагаем, что дерево разбито на поддеревья, а поддерево эта та группа элементов, которая единовременно доступна. Такие поддеревья назвали страницами.

(1)

Каждое обращение к странице имеет одно обращение к диску. Если на странице нарисовать 100 вершин, то поиск 10^6 элементов имеет log100 10^6=3. Потребует 3 обращение к странице. Для сильно ветвящихся деревьев необходима схема управления их ростом. Отказ от идеальной балансировки. Критерии: каждая страница кроме одной должна содержать при заданном постоянном n –задано, от n до 2*n элементов. Тогда для дерева с N элементами и максимальном размере странице 2*n элементов, в самом лучшем потребуется logn N. Такие структуры данных называются Б деревьями, у которых n - порядок. Такие деревья обладают следующими свойствами:

  1. Каждая страница содержит е более 2*n ключей

  2. Каждая страница кроме корневой содержит не менее n ключей

  3. Каждая страница представляют собой либо лист (нет потомков), либо имеет m+1 потомка, где m- реальное число ключей на этой страницу.

  4. Все странице листья находятся на одном уровне.

Пр. Б-дерево второго порядка n=2 с 3мя уровнями.

25

10 20 30 40

2 5 7 8 13 14 15 18 22 24 26 27 28 32 35 38 41 25

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

Пусть страница с n ключами имеет следующий вид.

p.K1p1K2p2…Kmpm аргумент поиска x-?

Пусть страница уже прочитана в оперативной памяти, тогда можно воспользоваться обычными методами поиска среди ключей, от K1 до Km. Если m большое, то бинарный поиск, если мало, то обычный линейный. Поиск в оперативной памяти пренебрежительно мал по сравнению с ??. если поиск не удачный, то может возникнуть одна из следующих ситуаций.

  1. Ki<x<Ki+1 -> поиск на pi

  2. Km<x -> pm

  3. X<K1 -> p0

Если указанная ссылка имеет значение nil то ключа х в дереве нет. Если элемент включает на страницу с m<2n, то процесс включения затрагивает только эту страницу. Если включение идет в полную страницу, то затрагивается структура дерева. Процесс приведет к появлению новых страниц. Тогда включение происходит в 3 шага.

  1. Обнаруживаем, что х отсутствует и включение на страницу С не возможно, т.к. она заполнена

  2. Страницу С разделяем на 2 страницы (вводится D новая страница)

  3. Ключи 2n+1 поровну распределяются между C и D. Средний ключ с исходной страницы С отправляем в родительскую страницу тогда поровну получаем. Получившиеся 2 страницы будут содержать ровно по n элементов, но включение в родительскую страницу может привести к ее переполнению. Распределение распространяются снизу-вверх. Если оно поднимется до самого корня, то может увеличиться высота дерева.

Вывод: Б – дерево растет снизу-вверх.

Пр.

A 20 30 x=22

B 7 10 15 18 C 20 30 35 38 D 35 38 m=2*n=4

22 26

A 20 30 (35) 40 50

B 7 10 15 18 21 22 23 25 31 33 37 38 42 45 46 47 60 65 100 120 35

Разработка программы. Будем пользоваться рекурсивной конструкцией так как процесс поиска страниц распространяется в обратном порядке. На странице ключи организует в виде массива.

Type PPtr=^Page; index=0..2*n; item=record //элемент key:integer; p:PPtr; count:word; end; page=record //массив элемента m:index; // диапазон номеров p0:PPtr; e:array [1..2*n] of item;

Алгоритм поиска и включения для Б – деревьев.

Поиск внутри страницы оформим как двоичный поиск в массиве е. Процедура вызывается, если поиск сигнализирует, что некоторый элемент необходимо передать вверх по дереву. Этот сигнал будет передавать через результирующий параметр h, фактически указывает на рост дерева. Если h истина, то должен быть параметр, содержащий передаваемый элемент. Включение начнется с мнимой страницы, так называемая специальная вершина и новый элемент сразу передается через параметр у, для реального включения уже листовой страницы.

Procedure search (x:integer; a:PPtr; var h:Boolean; var u:item);

Поиск х в дереве с корнем, а, если ключ нашли, то счетчик равен +1, если ключа нет, то включаем новый элемент с ключом равным х, если он передается вверх, то присваиваем ему выходной параметр u. h означает, что дерево стало выше.

элементу u присваиваем х h=true (u -> вверх)

A=nil

+

-

End

with a^ do

Двоичный поиск х в массиве е

{e[i].key}

х э e ?

+

Обработка count для элемента с key=x

-

Search (x,потомок, h,u)

h

-

+

m<2n

Включаем u на страницу a^ h=False

+

-

Расщепление страницы и передача вверх среднего элемента.

End with

Если после обращения к s в основной программе h=true, то требуется разделение страницы. Когда выходим на размещение новой корневой страницы и включаем в него единственного переданного элемента (u). Каждое обращение к search предполагает одной пересылки. Всего потребуется для дерева из n большое элементов максимум logn N. Необходимо иметь возможность накапливать до к страниц. Будем расщеплять страницу и средний элемент будет B

Getmem(b,sizeof(page));

R<=n

- {включение в правую страницу}

+ +

R=n?

V=u

-

V=en

I=n to (R+i) down to

ei=ei-1

eR+1 =u

i=1 tо n

m=n b^.m=n b^.p0=v^.p v^.p=b

End расш

b^.ei=a^.ei+n

R=R-n

V=ln+1

i=1 tо R-1

b^.ei=a^.ej+i+n

b^.eR=u

i=(R+1) tо n

b^.ei=a^.ei+n

Исключение из Б - дерева Этот процесс усложняется возможным слиянием страниц. 2 случая

  1. Исключаемый элемент находится на листовой странице

  2. Если удаляемый элемент на не листовой странице, то его нужно заменить одним из двух лексикографически смежных элементов.

Если смежный элемент находится на листовой странице, то исключить просто. Поиск смежного ключа похож на поиск в двоичном дереве: спускаться вниз вдоль правых ссылок, до листовой страницы p. Заменяем исключаемый элемент на правый элемент из страницы p и уменьшаем размер страницы p на 1. После уменьшения размера проверим число элементов на m и если оно меньше n, то условие B дерева нарушено и нужны дополнительные действия. Будем задействовать элемент с соседней страницы q. Обычно элементы поровну распределяются между p и q и называется это балансировкой. Если у q брать нечего, то p и q сливаем в одну страницу. Тогда элемент с родительской страницы спускаем на эти страницы. Затем q уничтожим. Процесс может идти до корня, тогда высота дерева может уменьшиться.

Procedure Underflow (var c,a;PPtr; s:word; var h:Boolean)

С - страница предок, а – не дополнившаяся страница s –индекс исключаемого из страницы элемента, h показатель высоты

Var b:pptr; i, k, mb, mc:word;

mc=c^.m

{a^.m=n-i}

-

s<mc

+ {b страница справа от а}

s=s+1 b=c^.e[s].p mb=b^.m k=(mb-n+1) div 2

a^.e[n]=c^.e[s] a^.e[n].p:=b^.p0

k>0

{слияние a и b}-

i=I to n

i=1 tо (k+1)

a^.e[n+i]=b^.e[i]

a^.m=2u c^.m=mc-1 h:=(mc<=h)

a^.e[i+1]=b^.e[i]

c^.e[s]=b^.e[k]; c^.e[s].p:=b

b^.p0=b^.e[k].p mb=mb-k

i=1 to mb

b^.m=mb a^.m=n-1+k h=False

b^.e[i]=b^.e[i+k]

-

S=1

B=c^.e[s-1].p

+

B=c^.p0

Mb=b^.m+1

K=(mb-n) div 2

передача элементов из b и a

+ -

сливание а и b

k>0

End

Вызывающий блок

Procedure Del(p:Pptr; var b:Boolean): var q:pptr;

А станица R элемент

With p^ do

q=e[m].p

-

q<>nil

P^.e[m].p=a^.e[R].p a^.e[R].p=p^.e[m] m=m-1 h:=m<n

+

Del (g,h)

H

-

+

Underflow (p,q,m,h)

End with

End Del

Соседние файлы в папке Лекции