Splay - дерево

Содержание

Слайд 2

Splay-дерево является двоичным деревом поиска. Это дерево принадлежит классу «саморегулирующихся деревьев»,

    Splay-дерево является двоичным деревом поиска. Это дерево принадлежит классу «саморегулирующихся

деревьев», которые поддерживают необходимый баланс ветвления дерева, чтобы обеспечить выполнение операций поиска, добавления и удаления за логарифмическое время от числа хранимых элементов. Это реализуется без использования каких-либо дополнительных полей в узлах дерева (как, например, в Красно-чёрных деревьях или АВЛ-деревьях, где в вершинах хранится, соответственно, цвет вершины и глубина поддерева). Вместо этого «расширяющие операции» (splay operation), частью которых являются вращения, выполняются при каждом обращении к дереву. 

ФПМИ БГУ

Слайд 3

ФПМИ БГУ Splay-дерево было придумано Робертом Тарьяном и Даниелем Слейтером в 1983 году.

ФПМИ БГУ

Splay-дерево было придумано Робертом Тарьяном и Даниелем Слейтером в 1983

году. 
Слайд 4

ФПМИ БГУ Splay-дерево позволяет находить быстрее те данные, которые использовались недавно.

ФПМИ БГУ

Splay-дерево позволяет находить быстрее те данные, которые использовались недавно. Для

того, чтобы доступ к недавно найденным данным был быстрее, надо, чтобы эти данные находились ближе к корню. Этого мы можем добиться, используя различные эвристики:
Слайд 5

ФПМИ БГУ Move to Root Cовершает повороты вокруг ребра (v, parent(v)),

ФПМИ БГУ

Move to Root

Cовершает повороты вокруг ребра (v, parent(v)), пока v

не окажется корнем дерева.

1

1

2

3

4

5

6

7

1

2

3

4

5

6

7

2

3

4

5

6

7

...

Слайд 6

ФПМИ БГУ Splay Также совершает повороты, но чередует различные виды поворотов,

ФПМИ БГУ

Splay

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

достигается логарифмическая амортизированная оценка. Будет подробно рассмотрена далее.

1

1

2

3

4

5

6

7

2

4

6

7

5

3

...

Слайд 7

ФПМИ БГУ При последовательном использовании операций "Move to Root" требуется 6

ФПМИ БГУ

При последовательном использовании операций "Move to Root" требуется 6 поворотов,

в то время как при использовании операции "Splay" достаточно 3 поворотов. 
Слайд 8

ФПМИ БГУ Операции со Splay-деревом

ФПМИ БГУ

Операции со Splay-деревом

Слайд 9

ФПМИ БГУ Splay Делится на несколько случаев: Zig (LL поворот, Правый

ФПМИ БГУ

Splay

Делится на несколько случаев:

Zig (LL поворот, Правый разворот, Малое правое

вращение)
Zag (RR поворот, Левый разворот, Малое левое вращение)
Zig-zig (Левый-левый случай, два разворота вправо)
Zag-zag (Правый-правый случай, два разворота влево)
Zig-zag (LR поворот, Большое правое вращение)
Zag-zig (RL-поворот, Большое левое вращение)
Слайд 10

ФПМИ БГУ Zig (LL поворот, Правый разворот) p v c b

ФПМИ БГУ

Zig (LL поворот, Правый разворот)

p

v

c

b

a

v

p

c

b

a

Слайд 11

ФПМИ БГУ Zag (RR поворот, Левый разворот) v p c b

ФПМИ БГУ

Zag (RR поворот, Левый разворот)

v

p

c

b

a

p

v

c

b

a

Слайд 12

ФПМИ БГУ Zig-zig (Левый-левый случай, два разворота вправо) p v c

ФПМИ БГУ

Zig-zig (Левый-левый случай, два разворота вправо)

p

v

c

b

a

v

p

b

a

g

d

p

v

b

a

g

d

c

g

d

c

Слайд 13

ФПМИ БГУ Zag-zag (Правый-правый случай, два разворота влево) p g c

ФПМИ БГУ

Zag-zag (Правый-правый случай, два разворота влево)

p

g

c

b

a

g

p

b

a

v

d

p

g

b

a

v

d

c

v

d

c

Слайд 14

ФПМИ БГУ Zig-zag (LR поворот, Большое правое вращение) g p a

ФПМИ БГУ

Zig-zag (LR поворот, Большое правое вращение)

g

p

a

d

v

c

b

g

d

v

p

c

b

a

v

p

b

a

g

d

c

Слайд 15

ФПМИ БГУ Zag-zig (RL-поворот, Большое левое вращение) v g b a

ФПМИ БГУ

Zag-zig (RL-поворот, Большое левое вращение)

v

g

b

a

p

d

c

g

p

v

d

c

b

a

g

v

b

a

p

d

c

Слайд 16

ФПМИ БГУ Данная операция занимает O(h) времени, где h — глубина вершины v.

ФПМИ БГУ

Данная операция занимает O(h) времени, где h — глубина вершины

v.
Слайд 17

ФПМИ БГУ Search Эта операция выполняется как для обычного бинарного дерева

ФПМИ БГУ

Search

Эта операция выполняется как для обычного бинарного дерева поиска, только

после нее запускается операция Splay. 

5

4

3

2

1

6

5

4

6

1

2

3

1

4

5

6

2

3

Search(1)

Search(1)

Zig-zig

Zig-zig

Слайд 18

ФПМИ БГУ Split Процедура Split получает на вход ключ и делит

ФПМИ БГУ

Split

Процедура Split получает на вход ключ и делит дерево на

два. В одном дереве все значения меньше ключа, а в другом — больше. Реализуется она просто. Нужно через Search найти ближайшую к ключу вершину, вытянуть ее вверх и потом отрезать либо левое, либо правое поддерево (либо оба).

5

4

3

2

1

6

3

4

5

6

2

1

Search(3)

3

4

5

6

2

1

Split

Слайд 19

ФПМИ БГУ Insert Чтобы вставить очередной ключ, достаточно вызвать Split по

ФПМИ БГУ

Insert

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

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

6

5

3

2

1

7

3

5

6

7

2

1

Split(4)

Insert(4)

4

3

2

1

5

6

7

Слайд 20

ФПМИ БГУ Merge У нас есть два дерева, причём подразумевается, что

ФПМИ БГУ

Merge

У нас есть два дерева, причём подразумевается, что все элементы

первого дерева меньше элементов второго. Запускаем Splay от самого большого элемента в первом дереве. Элемент становится корнем, при этом у него нет правого ребёнка. Ставим на его место второе дерево и возвращаем полученное дерево. 

6

7

8

5

4

1

2

3

Splay(3)

3

2

1

6

7

8

5

4

Merge

3

2

1

6

7

8

5

4

Слайд 21

ФПМИ БГУ Remove Для того, чтобы удалить вершину, поднимем ее вверх,

ФПМИ БГУ

Remove

 Для того, чтобы удалить вершину, поднимем ее вверх, а потом

выполним операцию Merge для её левого и правого поддеревьев. 

4

3

2

7

8

9

6

5

1

Splay(6)

4

3

2

7

8

9

6

5

1

Слайд 22

ФПМИ БГУ Remove(продолжение) Для того, чтобы удалить вершину, поднимем ее вверх,

ФПМИ БГУ

Remove(продолжение)

 Для того, чтобы удалить вершину, поднимем ее вверх, а потом

выполним операцию Merge для её левого и правого поддеревьев. 

4

3

2

7

8

9

6

5

1

Remove(6)

4

3

2

1

7

8

9

5

Слайд 23

ФПМИ БГУ Чтобы Splay-дерево поддерживало повторяющиеся ключи, можно поступить двумя способами.

ФПМИ БГУ

Чтобы Splay-дерево поддерживало повторяющиеся ключи, можно поступить двумя способами. Нужно

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

ФПМИ БГУ Заметим, что процедуры удаления, вставки, слияния и разделения деревьев

ФПМИ БГУ

Заметим, что процедуры удаления, вставки, слияния и разделения деревьев работают

за O(1) + время работы операции Search.
Процедура Search работает пропорционально глубине искомой вершины в дереве. По завершении поиска запускается процедура Splay, которая тоже работает пропорционально глубине вершины. Таким образом, достаточно оценить время работы процедуры Splay.
Слайд 25

ФПМИ БГУ Амортизационный анализ Splay-дерева проводится с помощью метода потенциалов. Потенциалом

ФПМИ БГУ

Амортизационный анализ Splay-дерева проводится с помощью метода потенциалов. Потенциалом рассматриваемого

дерева назовём сумму рангов его вершин. Ранг вершины v — это величина, обозначаемая rank(v) и равная logS(v), где S(v) — количество вершин в поддереве с корнем в v.
Слайд 26

ФПМИ БГУ Доказательство Рассмотрим идею доказательства. Если , утверждение очевидно. В

ФПМИ БГУ

Доказательство

Рассмотрим идею доказательства. 
Если      , утверждение очевидно. В противном случае рассмотрим, как

меняется ранг. Пусть изначально он равен               , а после i-ой итерации -                  . Для каждого этапа, кроме, быть может, последнего, мы покажем, что амортизационное время на его выполнение можно ограничить сверху величиной                                       . Для последнего этапа верхняя оценка составит                                               . Просуммировав верхние оценки и сократив промежуточные значения рангов мы получим требуемое:

Для этого рассмотрим три вида поворотов и изменение ранга при их использовании: Zig, Zig-zig, Zig-zag(Zag, Zag-zag, Zag-zig аналогично).

Лемма 
Амортизационная стоимость операции Splay от вершины v в дереве с корнем r составляет 3(rank(r) - rank(v)) + 1.

Слайд 27

ФПМИ БГУ r v c b a v' r' c b

ФПМИ БГУ

r

v

c

b

a

v'

r'

c

b

a

Zig(может выполняться только в конце)

Ранги меняются только у вершин v

и r

Используем размеры поддеревьев

Фактическое время выполнения поворота - 1

Слайд 28

ФПМИ БГУ Zig-zig Ранги меняются только у вершин v, p и

ФПМИ БГУ

Zig-zig

Ранги меняются только у вершин v, p и g

Фактическое время

выполнения поворота - 2

p

v

c

b

a

v'

p'

b

a

g

d

g'

d

c

Теперь нам осталось показать, что:

Тогда получим:

Слайд 29

ФПМИ БГУ Взглянув на диаграмму, заметим, что Тогда: Что и требовалось доказать.

ФПМИ БГУ

Взглянув на диаграмму, заметим, что 

Тогда:

Что и требовалось доказать.

Слайд 30

ФПМИ БГУ Zig-zag Ранги меняются только у вершин v, p и

ФПМИ БГУ

Zig-zag

Ранги меняются только у вершин v, p и g

Фактическое время

выполнения поворота - 2

g

p

a

d

v

c

b

v'

p'

b

a

g'

d

c

Далее аналогично предыдущему случаю

Слайд 31

ФПМИ БГУ Таким образом мы разобрали все три случая и получили

ФПМИ БГУ

Таким образом мы разобрали все три случая и получили верхнюю

оценку на амортизированное время через ранги.
Заметим, что ранг любой вершины ограничен логарифмом размера дерева. Делаем вывод, что операция Splay амортизационно выполняется за O(logn).
Слайд 32

ФПМИ БГУ Пусть — число раз, которое был запрошен элемент .

ФПМИ БГУ

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

выполнение запросов поиска на Splay-дереве выполняется за
По сути этот факт сообщает следующее. Пусть мы заранее знаем, в каком количестве будут заданы запросы для различных элементов. Мы строим какое-то конкретное бинарное дерево, чтобы отвечать на эти запросы как можно быстрее. Утверждение сообщает, что с точностью до константы Splay-дерево будет амортизационно работать не хуже, чем самое оптимальное фиксированное дерево, которое мы можем придумать. 

Теорема о статической оптимальности

Слайд 33

ФПМИ БГУ Пусть — это число запросов, которое мы уже совершили

ФПМИ БГУ

   Пусть —    это число запросов, которое мы уже совершили

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

Теорема о текущем множестве

Слайд 34

ФПМИ БГУ Исследование производительности и области применения Splay-деревьев оказалась темой для

ФПМИ БГУ

Исследование производительности и области применения Splay-деревьев оказалась темой для десятка

статей. Часть таких исследований показывает, что в сравнении с другими сбалансированными деревьями они проявляют себя наилучшим образом на практике. Высокая производительность объясняется особенностью реальных данных. Представьте себе ситуацию, когда у нас есть миллионы или даже миллиарды ключей, и лишь к некоторым из них обращаются регулярно, что весьма вероятно для многих типичных приложениях (в среднестатистическом приложении 80% обращений приходятся на 20% элементов).
Слайд 35

ФПМИ БГУ Splay-деревья стали наиболее широко используемой базовой структурой данных, изобретенной

ФПМИ БГУ

Splay-деревья стали наиболее широко используемой базовой структурой данных, изобретенной за

последние 30 лет, потому что они являются самым быстрым типом сбалансированного дерева поиска для огромного множества приложений.
Splay-деревья используются в Windows NT (в виртуальной памяти, сети и коде файловой системы), компиляторе gcc и библиотеке GNU C++, редакторе строк sed, сетевых маршрутизаторах Fore Systems, наиболее популярной реализации Unix malloc, загружаемых модулях ядра Linux и во многих других программах
Слайд 36

ФПМИ БГУ Главный недостаток заключается в том, что высота дерева всё-таки

ФПМИ БГУ

Главный недостаток заключается в том, что высота дерева всё-таки может

быть линейной. Например, если выполнить операцию Splay для всех элементов в неубывающем порядке. В таком случае время выполнения операций - O(n).
Однако амортизированная стоимость остаётся логарифмической. Проще говоря, при использовании Splay-дерева мы можем быть уверены, что m операций будут выполнены за время O(mlogn) при достаточно большом m.
Кроме того, изменение структуры дерева во время выполнения поиска усложняет его использование в многопоточной среде(представьте ситуацию, когда несколько потоков выполняют поиск одновременно).

Недостатки Splay-дерева

Слайд 37

ФПМИ БГУ Код реализации Splay-дерева можно найти по ссылке: https://github.com/magziim/DSA/blob/main/splay_tree.py

ФПМИ БГУ

  Код реализации Splay-дерева можно найти по ссылке:
https://github.com/magziim/DSA/blob/main/splay_tree.py