Толстая куча на избыточном счётчике — различия между версиями
Slavian (обсуждение | вклад) (Новая страница: «=Толстое дерево (статья пишется - ничего не трогать!)= {{Определение |id=def1. |neat = 1 |definition= Оп...») |
Slavian (обсуждение | вклад) |
||
Строка 12: | Строка 12: | ||
//[[Файл:ThickTreeExample.gif Пример толстых деревьев <tex>F_0, F_1, F_2, F_3</tex>]] | //[[Файл:ThickTreeExample.gif Пример толстых деревьев <tex>F_0, F_1, F_2, F_3</tex>]] | ||
− | |||
− | |||
== Свойства Толстых деревьев == | == Свойства Толстых деревьев == | ||
Строка 55: | Строка 53: | ||
'''Толстая куча''' — это '''почти кучеобразный''' '''нагруженный лес'''. | '''Толстая куча''' — это '''почти кучеобразный''' '''нагруженный лес'''. | ||
}} | }} | ||
+ | |||
+ | ==Представление толстой кучи== | ||
+ | Каждый узел толстой кучи будем представлять записью со следующими полями: | ||
+ | *<tex>Key</tex> {{---}} ключ элемента, приписанного узлу дерева | ||
+ | *<tex>Parent</tex> {{---}} указатель на родителя | ||
+ | *<tex>Lest</tex> {{---}} указатель на ближайшего левого брата | ||
+ | *<tex>Right</tex> {{---}} указатель на ближайшего правого брата | ||
+ | *<tex>LChild</tex> {{---}} указатель на самого левого сына | ||
+ | *<tex>Rank</tex> {{---}} ранг узла. | ||
+ | |||
+ | "Братья" связаны в двусвязный список при помощи указателей <tex>Left</tex> и <tex>Right</tex>. У самого левого (правого) "брата" в этом списке указатель <tex>Left</tex> (<tex>Right</tex>) равен <tex>NULL</tex>. | ||
+ | |||
+ | //[[Файл:ThickTreeExample.gif Пример толстых деревьев <tex>F_0, F_1, F_2, F_3</tex>]] | ||
+ | |||
+ | =Вспомогательные структуры= | ||
+ | |||
+ | |||
+ | |||
+ | =Основные операции= | ||
+ | * <tex>MakeHeap</tex> {{---}}<tex>O(1)</tex> | ||
+ | заключается в инициализации счетчиков. | ||
+ | * <tex>FindMin</tex> {{---}}<tex>O(1)</tex> | ||
+ | возвращает указатель на минимальный элемент. | ||
+ | * <tex>Insert(key)</tex> {{---}} <tex>O(1)</tex> | ||
+ | Чтобы выполнить эту операцию, делаем новый элемент отдельным деревом и выполняем процедуру вставки нового элемента ранга <tex>0</tex> в корневой счетчик. После этого, если необходимо, корректируем значение указателя на минимальный элемент. | ||
+ | * <tex>DecreaseKey</tex> {{---}} <tex>O(1)</tex> | ||
+ | Чтобы выполнить эту операцию, поступим следующим образом. Пусть <tex>x</tex> — узел, на который указывает указатель <tex>p</tex> . Вычитаем <tex>\delta</tex> из ключа узла <tex>x</tex> . Если новый ключ <tex>x</tex> меньше минимального ключа кучи <tex>H</tex>, обмениваем ключ элемента <tex>p</tex> с ключом минимального элемента. Новых нарушений операция не создаст. Пусть <tex>r</tex> — ранг <tex>x</tex> . Если <tex>x</tex> — нарушаемый узел, добавляем <tex>x</tex> как новое <tex>r</tex>-ранговое нарушение инкрементированием <tex>r</tex>-й цифры <tex>d_r</tex> счетчика нарушений. | ||
+ | * <tex>DeleteMin</tex> {{---}} <tex>O(\log(n))</tex> | ||
+ | Удаляем поддерево с корнем в минимальном узле из леса. Минимальность этого элемента гарантирует нам, что среди его детей нарушений порядка кучи не было. То есть нет необходимости работать со счетчиком нарушений. Затем вставляем в кучу все деревья с корнями, расположенными в детях удаляемого узла. Очевидно, что новый минимальный ключ — либо в корне дерева леса, либо в нарушенном узле. Выполняем поиск нового минимального элемента среди корней деревьев и нарушенных узлов. | ||
+ | Если минимальный элемент оказался в нарушенном узле, то обмениваем его с элементом, хранимым в корне этого дерева, корректируя корневой счетчик, если это необходимо. После замены новый минимум — в корне дерева леса. Этот корень будет новым минимальным узлом. | ||
+ | * <tex>Delete</tex> {{---}} <tex>O(\log(n))</tex> | ||
+ | <tex>DecreaseKey</tex> а затем <tex>DeleteMin</tex> | ||
+ | * <tex>Meld(h1, h2)</tex> {{---}} <tex>O(\log(n))</tex> | ||
+ | Первый шаг — фиксируются все нарушения в куче с меньшим максимальным рангом (разрывая связь произвольно). Не уменьшая общности, считаем, что эта куча — <tex>р2</tex> . Пройти по счетчику нарушений <tex>p2</tex> от младшей цифры к старшей, пропуская цифры со значением <tex>0</tex> . Для <tex>i</tex>-й цифры <tex>d_i != 0</tex> делаем операцию фиксирования на каждой цифре, показываемой прямым указателем <tex>d_i</tex> , если эта цифра имеет значение 2. Затем, если <tex>d_i = 2</tex> , фиксируем <tex>d_i</tex> . Если <tex>d_i = 1</tex> , преобразуем это <tex>i</tex>-ранговое нарушение в <tex>(i+1)</tex>-ранговое нарушение, как при фиксировании, используя <tex>i</tex>-рангового брата нарушенного узла вместо (несуществующего) другого <tex>i</tex> -рангового нарушения. | ||
+ | Как только <tex>h2</tex> не будет содержать каких-либо нарушений, нужно вставить корни из корневого счетчика <tex>h2</tex> в корневой счетчик <tex>h1</tex> инкрементированием соответствующих цифр. Если минимальный узел <tex>h2</tex> содержит меньший ключ, чем минимальный узел <tex>h1</tex> , следует установить новым минимальным узлом <tex>h1</tex> минимальный узел <tex>h2</tex> . Затем нужно вернуть модифицированную кучу <tex>h1</tex> в качестве результата <tex>Meld</tex> . | ||
+ | * <tex>DeleteViolation</tex> |
Версия 00:17, 22 мая 2013
Содержание
Толстое дерево (статья пишется - ничего не трогать!)
- Толстое дерево
- Толстое дерево ранга , для , состоит из трех деревьев ранга , связанных так, что корни двух из них являются самыми левыми потомками корня третьего.
//[[Файл:ThickTreeExample.gif Пример толстых деревьев
]]Свойства Толстых деревьев
Утверждение: |
Свойства толстых деревьев:
|
Определение: |
лес будем называть нагруженным, если он состоит из нескольких толстых деревьев, ранги которых не обязательно попарно различны и узлам которых взаимно однозначно поставлены в соответствие элементы взвешенного множества. |
Определение: |
Узел в нагруженном лесе назовем неправильным, если его ключ меньше ключа его родителя. |
Определение: |
Нагруженный лес назовем почти кучеобразным, если для каждого значения | в нем имеется не более двух неправильных узлов ранга .
Толстые кучи
Определение: |
Толстая куча — это почти кучеобразный нагруженный лес. |
Представление толстой кучи
Каждый узел толстой кучи будем представлять записью со следующими полями:
- — ключ элемента, приписанного узлу дерева
- — указатель на родителя
- — указатель на ближайшего левого брата
- — указатель на ближайшего правого брата
- — указатель на самого левого сына
- — ранг узла.
"Братья" связаны в двусвязный список при помощи указателей
и . У самого левого (правого) "брата" в этом списке указатель ( ) равен .//[[Файл:ThickTreeExample.gif Пример толстых деревьев
]]Вспомогательные структуры
Основные операции
- —
заключается в инициализации счетчиков.
- —
возвращает указатель на минимальный элемент.
- —
Чтобы выполнить эту операцию, делаем новый элемент отдельным деревом и выполняем процедуру вставки нового элемента ранга
в корневой счетчик. После этого, если необходимо, корректируем значение указателя на минимальный элемент.- —
Чтобы выполнить эту операцию, поступим следующим образом. Пусть
— узел, на который указывает указатель . Вычитаем из ключа узла . Если новый ключ меньше минимального ключа кучи , обмениваем ключ элемента с ключом минимального элемента. Новых нарушений операция не создаст. Пусть — ранг . Если — нарушаемый узел, добавляем как новое -ранговое нарушение инкрементированием -й цифры счетчика нарушений.- —
Удаляем поддерево с корнем в минимальном узле из леса. Минимальность этого элемента гарантирует нам, что среди его детей нарушений порядка кучи не было. То есть нет необходимости работать со счетчиком нарушений. Затем вставляем в кучу все деревья с корнями, расположенными в детях удаляемого узла. Очевидно, что новый минимальный ключ — либо в корне дерева леса, либо в нарушенном узле. Выполняем поиск нового минимального элемента среди корней деревьев и нарушенных узлов. Если минимальный элемент оказался в нарушенном узле, то обмениваем его с элементом, хранимым в корне этого дерева, корректируя корневой счетчик, если это необходимо. После замены новый минимум — в корне дерева леса. Этот корень будет новым минимальным узлом.
- —
а затем
- —
Первый шаг — фиксируются все нарушения в куче с меньшим максимальным рангом (разрывая связь произвольно). Не уменьшая общности, считаем, что эта куча —
. Пройти по счетчику нарушений от младшей цифры к старшей, пропуская цифры со значением . Для -й цифры делаем операцию фиксирования на каждой цифре, показываемой прямым указателем , если эта цифра имеет значение 2. Затем, если , фиксируем . Если , преобразуем это -ранговое нарушение в -ранговое нарушение, как при фиксировании, используя -рангового брата нарушенного узла вместо (несуществующего) другого -рангового нарушения. Как только не будет содержать каких-либо нарушений, нужно вставить корни из корневого счетчика в корневой счетчик инкрементированием соответствующих цифр. Если минимальный узел содержит меньший ключ, чем минимальный узел , следует установить новым минимальным узлом минимальный узел . Затем нужно вернуть модифицированную кучу в качестве результата .