59
Лекция 5. Деревья. Часть 2. Мацкевич С. Е.

Алгоритмы и структуры данных осень 2013 лекция 6

Embed Size (px)

Citation preview

Page 1: Алгоритмы и структуры данных осень 2013 лекция 6

Лекция 5.Деревья. Часть 2.

Мацкевич С. Е.

Page 2: Алгоритмы и структуры данных осень 2013 лекция 6

План лекции «Деревья. Часть 2.»

Декартовы деревья

Красно-черные деревья

АТД «Ассоциативный массив»

RMQ – Range Minimum (Maximum) Query

Разреженная таблица (Sparse Table)

Дерево отрезков

2

Page 3: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

Декартово дерево – это структура данных, объединяющая в себе двоичное дерево поиска и двоичную кучу.

Определение 1. Декартово дерево – двоичное дерево, в узлах которого хранится пары 𝑥, 𝑦 , где 𝑥 – это ключ, а 𝑦 – это приоритет. Все 𝑥 и все 𝑦 являются различными. Если некоторый элемент дерева содержит 𝑥0, 𝑦0 , то у всех элементов в левом поддереве 𝑥 < 𝑥0, у всех элементов в правом поддереве 𝑥 > 𝑥0, а

также и в левом, и в правом поддереве 𝑦 < 𝑦0.

Таким образом, декартово дерево является двоичным деревом поиска по 𝑥 и кучей по 𝑦.

3

Page 4: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

Другие названия:* treap (tree + heap),* дуча (дерево + куча),* дерамида (дерево + пирамида),* курево (куча + дерево).

Изобретатели –Сидель иАрагон (1989г)

4

Page 5: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

Теорема 1. В декартовом дереве из n узлов, приоритеты которого являются случайными величинами c равномерным распределением, средняя глубина дерева 𝑂 log 𝑛 .

Без доказательства.

5

Page 6: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

Основные операции:

Разрезание – Split,

Слияние – Merge.

На основе этих двух операций реализуются операции:

Вставка

Удаление.

6

Page 7: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

Разрезание – Split

Операция «разрезать» позволяет разрезать декартово дерево 𝑇 по ключу 𝐾 и получить два других декартовых дерева: 𝑇1 и 𝑇2, причем в 𝑇1 находятся все ключи дерева 𝑇, не большие 𝐾, а в 𝑇2 – большие 𝐾.

7

Page 8: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

8

// Разрезание декартового дерева по ключу.void Split( CTreapNode* currentNode, int key, CTreapNode*& left,

CTreapNode*& right ){

if( currentNode == 0 ) {left = 0;right = 0;

} else if( currentNode->Key <= key ) {Split( currentNode->Right, key, currentNode->Right, right );left = currentNode;

} else {Split( currentNode->Left, key, left, currentNode->Left );right = currentNode;

}}

Page 9: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

Слияние – Merge

Операция «слить» позволяет слить два декартовых дерева в одно. Причем, все ключи в первом (левом) дереве должны быть меньше, чем ключи во втором (правом). В результате получается дерево, в котором есть все ключи из первого и второго деревьев.

9

Page 10: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

10

// Слияние двух декартовых деревьев.CTreapNode* Merge( CTreapNode* left, CTreapNode* right ){

if( left == 0 || right == 0 ) {return left == 0 ? right : left;

}if( left->Priority > right->Priority ) {

left->Right = Merge( left->Right, right );return left;

}right->Left = Merge( left, right->Left );return right;

}

Page 11: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

Вставка

Добавляется элемент (x, y), где x – ключ, а y – приоритет.

Элемент (x, y) – это декартово дерево из одного элемента. Для того чтобы его добавить в наше декартово дерево T, очевидно, нужно их слить. Но T может содержать ключи как меньше, так и больше ключа x, поэтому сначала нужно разрезать T по ключу x.

Реализация №1.

1. Разобьём наше дерево по ключу x, который мы хотим добавить, на поддеревья 𝑇1 и 𝑇2.

2. Сливаем первое дерево 𝑇1 с новым элементом.

3. Сливаем получившиеся дерево со вторым 𝑇2.

11

Page 12: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

Вставка

Реализация №2.

1. Сначала спускаемся по дереву (как в обычном бинарном дереве поиска по x), но останавливаемся на первом элементе, в котором значение приоритета оказалось меньше y.

2. Теперь разрезаем поддерево найденного элемента на 𝑇1 и 𝑇2.

3. Полученные 𝑇1 и 𝑇2 записываем в качестве левого и правого сына добавляемого элемента.

4. Полученное дерево ставим на место элемента, найденного в первом пункте.

В первой реализации два раза используется Merge, а во второй реализации слияние вообще не используется.

12

Page 13: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

Удаление.

Удаляется элемент с ключом x.

Реализация №1.

1. Разобьём дерево по ключу x, который мы хотим удалить, на 𝑇1и 𝑇2.

2. Теперь отделяем от первого дерева 𝑇1 элемент x, разбивая по ключу 𝑥 − 𝜀 .

3. Сливаем измененное первое дерево 𝑇1 со вторым 𝑇2.

13

Page 14: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

Удаление.

Реализация №2.

1. Спускаемся по дереву (как в обычном двоичном дереве поиска по x), ища удаляемый элемент.

2. Найдя элемент, вызываем слияние его левого и правого сыновей.

3. Результат процедуры ставим на место удаляемого элемента.

В первой реализации два раза используется Split, а во второй реализации разрезание вообще не используется.

14

Page 15: Алгоритмы и структуры данных осень 2013 лекция 6

Декартовы деревья

Расход памяти и время работы.

15

В среднем случае В худшем случае

Расход памяти O(n) O(n)

Поиск O(log n) O(n)

Вставка O(log n) O(n)

Удаление O(log n) O(n)

Page 16: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья

Красно-черное дерево – двоичное дерево поиска, в котором баланс осуществляется на основе "цвета" узла дерева, который принимает только два значения: "красный" и "чёрный".

Все листья дерева являются фиктивными и не содержат данных, но относятся к дереву и являются чёрными.

Для экономии памяти фиктивные листья делают одним общим фиктивным листом.

Изобретатель –Рудольф Байер (1972г).

16

Page 17: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья

Определение 2. Красно-черное дерево – двоичное дерево поиска, у которого каждому узлу сопоставлен дополнительный атрибут – цвет и для которого выполняются следующие свойства:

1. Каждый узел промаркирован красным или чёрным цветом.

2. Корень и конечные узлы (листья) дерева – чёрные.

3. У красного узла родительский узел – чёрный.

4. Все простые пути из любого узла x до листьев содержат одинаковое количество чёрных узлов.

17

Page 18: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья

Определение 3. Черная высота вершины x – число черных вершин на пути из x в лист, не учитывая саму вершину x.

Пример.

Для вершин «-16» и «-88»черная высота = 1.

Для вершин «-7» и «0»черная высота = 2.

18

Page 19: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья

Теорема 2. Красно-черное дерево с 𝑁 ключами имеет высотуℎ = 𝑂 log𝑁 .

Лемма 1. В красно-черном дереве с черной высотой ℎ𝑏 количество внутренних вершин не менее 2ℎ𝑏+1 − 1.

Доказательство Леммы 1. По индукции. Предположение индукции: Если черная высота дерева не меньше 𝐻, то количество внутренних вершин не менее 2𝐻+1 − 1.Для листа (фиктивной вершины) лемма верна.Рассмотрим внутреннюю вершину 𝑥.Пусть ее черная высота ℎ𝑏 𝑥 = 𝐻 + 1. Если ее потомок 𝑝 – черный, то черная высота такого потомка ℎ𝑏 𝑝 = 𝐻. Если потомок 𝑝 – красный, то черная высота такого потомка ℎ𝑏 𝑝 = 𝐻 + 1. В любом случае по предположению индукции в каждом поддереве содержится не менее 2𝐻+1 − 1 вершин.Тогда во всем дереве не менее 2 ∙ 2𝐻+1 − 1 + 1 = 2𝐻+2 − 1, ч.т.д.

19

Page 20: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья

Доказательство Теоремы 2. Если обычная высота равна ℎ, то черная высота дерева будет не меньше ℎ 2 − 1. По лемме 1 количество внутренних вершин 𝑁 в дереве

𝑁 ≥ 2 ℎ 2 − 1.Прологарифмируем:

log 𝑁 + 1 ≥ ℎ 2 .

Итого,

ℎ ≤ 2 ∙ log 𝑁 + 1 ,

т. е.

ℎ = 𝑂 log 𝑁 .

20

Page 21: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Вставка

Вставка элемента.

Каждый элемент вставляется вместо листа.

Для выбора места вставки идём от корня в нужную сторону, как в наивном методе построения дерева поиска. До тех пор, пока не остановимся в листе (в фиктивной вершине).

Вставляем вместо листа новый элемент красного цветас двумя листами-потомками.

Теперь восстанавливаем свойства красно-черного дерева.Если отец нового элемента черный, то ничего делать не надо.Если отец нового элемента красный, то достаточно рассмотреть только два случая:

21

Page 22: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Вставка

Случай 1. «Дядя» этого узла тоже красный. Тогда перекрашиваем «отца» и «дядю» в чёрный цвет, а «деда» - в красный.

Теперь «дед» может нарушать свойство дерева.«Прадед» может быть красного цвета.

Так рекурсивно пытаемся восстановить свойствадерева, двигаясь к предкам.

Если в результате этих перекрашиваний мы дойдём до корня, то в нём в любом случае ставим чёрный цвет.

22

Page 23: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Вставка

Случай 2. «Дядя» черный и правый. Просто выполнить перекрашивание отца в черный цвет нельзя, чтобы не нарушить постоянство чёрной высоты дерева по ветви с отцом.

1) Если добавленный узел X был правымпотомком отца A,то необходимо сначала выполнить левоевращение, которое сделает отца A левымпотомком X.2) Выполняем правый поворот A и B.Перекрашиваем A и B.Больше ничего делать не требуется.

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

23

Page 24: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Вставка

24

// Вставка узла с заданным ключом.void CRBTree::Insert( double key ){

CRBNode* x = root; // Корень может быть nil.CRBNode* y = nil; // Узел, под который будем вставлять.while( x != nil ) {

y = x;x = key < x->Key ? x->Left : x->Right;

}CRBNode* z = new CRBNode( key );z->Parent = y;if( y == nil ) // Дерево пусто.

root = z;else if( key < y->Key )

y->Left = z;else

y->Right = z;z->Left = z->Right = nil;z->Color = Red;InsertFixup( z ); // Восстановление свойств.

}

Page 25: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Вставка

Последовательность обработки.

Случай 1, конец. Если родитель – черный или пришли в корень.

Случай 1 → Случай 1.

Случай 1 → Случай 2, конец.

Случай 2, конец.

Длинная цепочка только:Случай 1 → Случай 1 → Случай 1 → … → Случай 1 → Случай X, конец.При этом один переход – переход к отцу x.

Общее время работы вставки – 𝑂 log𝑁 .

25

Page 26: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Удаление

Удаление вершины.

При удалении вершины могут возникнуть три случая в зависимости от количества её детей:

1. Если у вершины нет детей, то изменяем указатель на неё у родителя на фиктивный лист.

2. Если у неё только один ребёнок, то делаем у родителя ссылку на ребенка вместо этой вершины.

26

Page 27: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Удаление

3. Если же имеются оба ребёнка, то находим вершину со следующим значением ключа. У такой вершины нет левого ребёнка. Удаляем уже эту вершину способом, описанным в первом или во втором пункте, скопировав её ключ в изначальную вершину.

Вершина со следующимзначением ключа –самая левая вершинав правом поддереве.Для вершины 13 – 15.Для вершины 17 – 22.

27

Page 28: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Удаление

Итак, удаляется вершина, имеющая не более одной дочерней.

А. Удаление красной вершины.

При удалении красной вершины свойства дерева не нарушаются.Более того, красная вершина, не может иметь одного потомка. Если бы потомок существовал, то он был бы черным и нарушилось бы свойство постоянства черной глубины для потомка и его соседней фиктивной вершины.

Действие:* Удалить красную вершину (заменить на лист).

Восстановление свойств потребуется только при удалении чёрной.

28

Page 29: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Удаление

Б. Удаление черной вершины с потомком.

Единственным потомком черной вершины может быть только красная вершина. Иначе нарушилось бы свойство постоянства черной глубины для потомка и его соседней фиктивной вершины.

Действия:* В черную вершину заносим данные красной.* Удаляем красную (заменяем на лист).

29

Page 30: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Удаление

В. Удаление черной вершины без потомков. Это самый сложный случай.

Действия:* Удалим черную вершину (заменим на лист).* Лист на месте удаленной вершины обозначим «x».

Путь в «x» имеет меньшее количество черных вершин (черную глубину), чем в другие вершины. Будем помнить об этом и называть «x» дважды черным.

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

30

Page 31: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Удаление

31

Если вершина x – корень.

* Оставим корень просто черным (один раз черным).

Так черная глубина всего дерева уменьшится на 1.

Восстановление свойств. Случай 0.

Page 32: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Удаление

32

Если брат b вершины x – красный.

* Делаем вращение вокруг ребра между отцом a и братом b, тогда брат становится родителем отца.* Красим нового деда b в чёрный, а отца a – в красный цвет.

Теперь брат x – черный.

Восстановление свойств. Случай 1.

Page 33: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Удаление

33

Если брат b вершины x – черный, и оба дочерних узла брата c и d –черные. c и d могут быть листьями.

* Красим брата b в красный цвет. Так поддеревья x и b теперь недокрашены в черный.* Если отец a был красного цвета, то красим его в черный и завершаем работу. Так черная глубина a восстановится.Иначе, считаем отца a дважды черным, рассматриваем его как x.

Восстановление свойств. Случай 2.

Page 34: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Удаление

34

Если брат b вершины x – черный, левый ребенок брата c – красный, а правый d – черный.

* Делаем правое вращение c – b.* Красим b в красный цвет.* Красим c в черный цвет.

Так у брата правый ребенок станет красным.

Восстановление свойств. Случай 3.

Page 35: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Удаление

35

Если брат b вершины x – черный, правый ребенок брата d – красный.

* Делаем левое вращение b – a.* Красим b в цвет, который был у a.* Красим a в черный цвет.

Так черная глубина x увеличится на 1, то есть восстановится. Конец.

Восстановление свойств. Случай 4.

Page 36: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Удаление

36

// Удаление вершины.void CRBTree::Delete( CRBNode* z){

CRBNode* y = nil; // Реально удаляемая вершина.if( z->Left == nil || z->Right == nil )

y = z;else

y = Next( z );// Дважды черная.CRBNode* x = y->Left != nil ? y->Left : y->Right;x->Parent = y->Parent;if( y->Parent == nil ) // Удаляется корень.

root = x;else if( y == y->Parent->Left )

y->Parent->Left = x;else

y->Parent->Right = x;if( y != z )

z->Key = y->Key;if( y->Color == Black )

DeleteFixup( x ); // Восстановление свойств.delete y;

}

Page 37: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья. Удаление

37

Последовательность обработки при восстановлении свойств.

Случай 1 → Случай 2, конец, т. к. отец x – красный.

Случай 3 → Случай 4, конец.

Случай 4, конец.

Случай 2 → любой случай, в том числе Случай 0 и Случай 2.

Длинная цепочка только:Случай 2 → Случай 2 → Случай 2 → … → Случай 2 → Случай X, конец.При этом один переход – переход к отцу x.

Общее время работы удаления – 𝑂 log𝑁 .

Восстановление свойств.

Page 38: Алгоритмы и структуры данных осень 2013 лекция 6

Красно-черные деревья

Расход памяти и время работы.

38

В среднем случае В худшем случае

Расход памяти O(n) O(n)

Поиск O(log n) O(log n)

Вставка O(log n) O(log n)

Удаление O(log n) O(log n)

Page 39: Алгоритмы и структуры данных осень 2013 лекция 6

АТД «Ассоциативный массив»

Определение 4. Ассоциативный массив – абстрактный тип данных, позволяющий хранить пары вида «(ключ, значение)» и поддерживающий операции добавления пары, а также поиска и удаления пары по ключу:

INSERT(ключ, значение).

FIND(ключ). Возвращает значение, если есть пара с заданным ключом.

REMOVE(ключ).

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

39

Page 40: Алгоритмы и структуры данных осень 2013 лекция 6

АТД «Ассоциативный массив»

Расширение ассоциативного массива.

Обязательные три операции часто дополняются другими. Наиболее популярные расширения включают следующие операции:

CLEAR — удалить все записи.

EACH — «пробежаться» по всем хранимым парам

MIN — найти пару с минимальным значением ключа

MAX — найти пару с максимальным значением ключа

В последних двух случаях необходимо, чтобы на ключах была определена операция сравнения.

40

Page 41: Алгоритмы и структуры данных осень 2013 лекция 6

АТД «Ассоциативный массив»

Реализации ассоциативного массива.

Массив пар, упорядоченный по ключу. Поиск – бинарный.

Время поиска 𝑂 log𝑛 . Время вставки и удаления 𝑂 𝑛 .

Сбалансированное дерево поиска.

Время работы операций поиска, вставки и удаления –𝑂 log 𝑛 .

std::map реализован на основе красно-черного дерева.

Хеш-таблицы.

Все операции в среднем – 𝑂 1 , в худшем – 𝑂 𝑛 .

41

Page 42: Алгоритмы и структуры данных осень 2013 лекция 6

RMQ

Задача поиска минимумов в отрезках массива (RMQ).Пусть дан массив A[0..n-1]. Требуется отвечать на запросы вида «найти минимум на отрезке с i-ого элемента по j-ый».

RMQ расшифровывается как Range Minimum (Maximum) Query –запрос минимума (максимума) на отрезке в массиве. Будем рассматривать операцию взятия минимума.

Пример:

Минимум на отрезке со второго элемента по седьмой равен двум.

42

Page 43: Алгоритмы и структуры данных осень 2013 лекция 6

RMQ

Наивное решение 1:

Ответ на каждый запрос находить, просто пробегаясь по всем элементам массива, лежащим на нужном отрезке.

Такое решение не является самым эффективным. В худшем случае придётся пробежаться по O(n) элементам, т.е. временная сложность этого алгоритма – O(n) на один запрос.

Задачу можно решить эффективнее.

43

Page 44: Алгоритмы и структуры данных осень 2013 лекция 6

RMQ

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

Наивное решение 2:

Препроцессинг: для каждой пары (i, j) посчитаем минимум P[i][j] на отрезке A[i..j].

Время поиска минимума для одного отрезка – 𝑂 𝑛 .

Время препроцессинга (поиск минимумов для всех отрезков) 𝑃 𝑛 =𝑂 𝑛3 .

Можно сделать подсчет всех минимумов за 𝑂 𝑛2 .

Время на выполнение одного запроса – 𝑄 𝑛 = 𝑂 1 .

Итого, время работы наивного решения 2: (𝑂 𝑛2 , 𝑂 1 ).

Дополнительная память: 𝑂 𝑛2 .

44

Page 45: Алгоритмы и структуры данных осень 2013 лекция 6

RMQ. Разреженная таблица

Определение 5. Разреженная таблица (Sparse Table) – это такая таблица ST[][], что ST[k][i] есть минимум A на полуинтервале

𝑖, 𝑖 + 2𝑘 .

Она содержит минимумы на всех отрезках, длина которых есть степень двойки.

45

Page 46: Алгоритмы и структуры данных осень 2013 лекция 6

RMQ. Разреженная таблица

Вычисление Разреженной таблицы.

ST[0] есть массив A.

Далее воспользуемся свойством:

𝑆𝑇 𝑘 𝑖 = min 𝑆𝑇 𝑘 − 1 𝑖 , 𝑆𝑇 𝑘 − 1 𝑖 + 2𝑘−1 .

Благодаря этому свойству мы можем сначала посчитать динамически ST[1], потом ST[2] и т. д.

В таблице 𝑂 𝑛 log 𝑛 элементов. Каждое значение вычисляется за 𝑂 1 времени.

Время препроцессинга 𝑃 𝑛 = 𝑂 𝑛 log 𝑛 .

46

Page 47: Алгоритмы и структуры данных осень 2013 лекция 6

RMQ. Разреженная таблица

Любой отрезок массива разбивается на два перекрывающихся подотрезкадлиною в степень двойки.

Формула для вычисления RMQ(i, j) по разреженной таблице.

Пусть 𝑘 = log 𝑗 − 𝑖 + 1 . Тогда

𝑅𝑀𝑄 𝑖, 𝑗 = min 𝑆𝑇 𝑖, 𝑘 , 𝑆𝑇 𝑗 − 2𝑘 + 1, 𝑘 .

Время работы вычисления RMQ – O( 1 ).

Но надо вычислить k – логарифм от j – i + 1. Для этого все логарифмы от 1 до n предпосчитывают во время препроцессинга.

Итого, время работы RMQ с разреженной таблицей: 𝑂 𝑛 log𝑛 , 𝑂 1 .

Дополнительная память: 𝑂 𝑛 log𝑛 .

47

Page 48: Алгоритмы и структуры данных осень 2013 лекция 6

Дерево отрезков

48

Page 49: Алгоритмы и структуры данных осень 2013 лекция 6

Дерево отрезков

Определение 6. Дерево отрезков – дерево, листьями которого являются элементы исходного массива. Другие вершины этого дерева имеют по 2 ребёнка и содержат результат операции от своих детей (например, минимум или сумму).

n – степень двойки.

Корень содержит результат искомой функции от всего массива [0...n–1], левый ребёнок корня содержит результат функции на [0...n/2–1], а правый, соответственно результат на [n/2…n-1]. И так далее, продвигаясь вглубь дерева.

49

Page 50: Алгоритмы и структуры данных осень 2013 лекция 6

Дерево отрезков

Построение дерева отрезков.

Дан массив A. Увеличим его длину до степени двойки. 𝑛 = 2𝑘 .Заполним новые элементы «∞» для поиска минимума, либо «0» для поиска суммы.

Хранить дерево отрезков будем в массиве длины 2𝑘+1.

Навигация к дочерним и к родительским узлам как в куче (пирамиде):Left(i) = 2i + 1,Right(i) = 2i + 2,Parent(i) = (i–1)/2.

50

Page 51: Алгоритмы и структуры данных осень 2013 лекция 6

Дерево отрезков

Построение дерева отрезков.

Выделяют два основных способа построения дерева отрезков: построение снизу и построение сверху.

При построении снизу алгоритм поднимается от листьев к корню.Элементы массива заполняются от большего индекса к меньшему, таким образом, при заполнении элемента i его дети 2i+1 и 2i+2уже будут заполнены.

При построении сверху спускается от корня к листьям.

Время работы пропорционально длине массива T – 𝑂 𝑛 .

51

Page 52: Алгоритмы и структуры данных осень 2013 лекция 6

Дерево отрезков

52

// Построение дерева отрезков сверху. Рекурсивно.void TreeBuild1( const vector<int>& a, vector<int>& t,

int i, int l, int r ){

// Мы находимся в элементе с номером i, который отвечает// за полуинтервал [l, r).if( l == r )

return;if( r - l == 1 )

t[i] = a[l];else

int m = ( l + r ) / 2; // Середина отрезка.TreeBuild1(a, 2 * i + 1, l, m);TreeBuild1(a, 2 * i + 2, m, r);t[i] = f(t[2 * i + 1], t[2 * i + 2]);

}

Page 53: Алгоритмы и структуры данных осень 2013 лекция 6

Дерево отрезков

Запрос минимума.

Назовём фундаментальным отрезком в массиве такой отрезок, что существует вершина в дереве, которой он соответствует.

53

Page 54: Алгоритмы и структуры данных осень 2013 лекция 6

Дерево отрезков

Запрос минимума.

Разобьём отрезок запроса на минимальное количество непересекающихся фундаментальных.

Утверждение. На каждом уровне их количество не превосходит 2.

Доказательство. Возьмём самый большой фундаментальный отрезок в разбиении. Пусть его длина – 2𝑡 . Заметим, что фундаментальных отрезков длиной 2𝑡 – не более двух.Возьмём самый левый из имеющихся максимальных фундаментальных. Будем двигаться от него налево. Заметим, что длины отрезков будут убывать. Так же и с правым из максимальных. Тем самым получим, что фундаментальных отрезков – не более 2𝑡, что не превосходит 2 log 𝑛.

54

Page 55: Алгоритмы и структуры данных осень 2013 лекция 6

Дерево отрезков

Запрос минимума.

Будем подниматься снизу, добавляя к ответу на каждом уровне, если надо, фундаментальный отрезок.

Заведём два указателя – l и r, с помощью которых будем находить очередные фундаментальные отрезки разбиения. Изначально установим l и r указывающими на листы, соответствующие концам отрезка запроса. Заметим, что если l указывает на вершину, являющуюся правым сыном своего родителя, то эта вершина принадлежит разбиению на фундаментальные отрезки, в противном случае не принадлежит. Аналогично с указателем r – если он указывает на вершину, являющуюся левым сыном своего родителя, то добавляем её в разбиение. После этого сдвигаем оба указателя на уровень выше и повторяем операцию. Продолжаем операции пока указатели не зайдут один за другой.

55

Page 56: Алгоритмы и структуры данных осень 2013 лекция 6

Дерево отрезков

56

// Поиск минимума снизу.int RMQUp( const vector<int>& T, int l, int r ){

int answer = INF;int n = T.size() / 2;l += n – 1;r += n – 1;while( l <= r ) {

// Если l – правый сын своего родителя, учитываем его.if( l & 1 == 0 )

answer = min( answer, T[l] );// Если r – левый сын своего родителя, учитываем его.if( r & 1 == 1 )

answer = min( answer, T[r] );// Сдвигаем указатели на уровень выше.l = l / 2;r = ( r – 2 ) / 2;

}return answer;

}

Page 57: Алгоритмы и структуры данных осень 2013 лекция 6

Дерево отрезков

Запрос минимума.

Асимптотика работы алгоритма – 𝑂 log 𝑛 , т. к. на каждом уровне мы выполняем константное число операций, а всего уровней –

log 𝑛.

Запрос суммы выполняется аналогично.

57

Page 58: Алгоритмы и структуры данных осень 2013 лекция 6

RMQ. Сравнение

Реализация Препроцессинг Запрос

Полный просчет 𝑂 𝑛2 𝑂 1

Разреженная таблица 𝑂 𝑛 log 𝑛 𝑂 1

Дерево отрезков 𝑂 𝑛 𝑂 log 𝑛

58

Page 59: Алгоритмы и структуры данных осень 2013 лекция 6

Вопросы?

Спасибо за внимание!