Толстая куча на избыточном счётчике — различия между версиями
Slavian (обсуждение | вклад) (→Счетчик нарушений) |
Slavian (обсуждение | вклад) (→Основные операции) |
||
Строка 167: | Строка 167: | ||
Как только <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>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> | * <tex>DeleteViolation</tex> | ||
+ | для освобождения кучи от нарушений достаточно выполнить следующий псевдокод: | ||
+ | <code> | ||
+ | for i:=0 to h2.MaxRank do | ||
+ | if (CountViolation[i].Value = 2) | ||
+ | FixCountViolation(i); | ||
+ | for i:=0 to h2.MaxRank do | ||
+ | if(CountViolation[i].Value = 1) | ||
+ | IncCountViolation(i, SearchBrother(CountViolation[i].rmFirstviolation)); | ||
+ | FixCountViolation(i); | ||
+ | </code> | ||
− | + | =Источники= | |
* [http://www.intuit.ru/studies/courses/100/100/lecture/1543?page=1 Толстые кучи — INTUIT.ru] | * [http://www.intuit.ru/studies/courses/100/100/lecture/1543?page=1 Толстые кучи — INTUIT.ru] | ||
[[Категория: Дискретная математика и алгоритмы]] | [[Категория: Дискретная математика и алгоритмы]] | ||
[[Категория: Приоритетные очереди]] | [[Категория: Приоритетные очереди]] |
Версия 23:45, 22 мая 2013
Содержание
Толстое дерево (статья пишется - ничего не трогать!)
- Толстое дерево
- Толстое дерево ранга , для , состоит из трех деревьев ранга , связанных так, что корни двух из них являются самыми левыми потомками корня третьего.
//[[Файл:ThickTreeExample.gif Пример толстых деревьев
]]Свойства Толстых деревьев
Утверждение: |
Свойства толстых деревьев:
|
Определение: |
лес будем называть нагруженным, если он состоит из нескольких толстых деревьев, ранги которых не обязательно попарно различны и узлам которых взаимно однозначно поставлены в соответствие элементы взвешенного множества. |
Определение: |
Узел в нагруженном лесе назовем неправильным, если его ключ меньше ключа его родителя. |
Определение: |
Нагруженный лес назовем почти кучеобразным, если для каждого значения | в нем имеется не более двух неправильных узлов ранга .
Толстые кучи
Определение: |
Толстая куча — это почти кучеобразный нагруженный лес. |
Представление толстой кучи
Каждый узел толстой кучи будем представлять записью со следующими полями:
- — ключ элемента, приписанного узлу дерева
- — указатель на родителя
- — указатель на ближайшего левого брата
- — указатель на ближайшего правого брата
- — указатель на самого левого сына
- — ранг узла.
"Братья" связаны в двусвязный список при помощи указателей
и . У самого левого (правого) "брата" в этом списке указатель ( ) равен .//[[Файл:ThickTreeExample.gif Пример толстых деревьев
]]Вспомогательные структуры
Нам понадобятся понятия корневого счетчика и счетчика нарушений.
Толстую кучу будем представлять записью следующего вида:
, где:— массив, соответствующий корневому счетчику
— массив, соответствующий счетчику нарушений
— указатель на элемент кучи с минимальным ключом
— наибольший ранг среди рангов деревьев, присутствующих в куче
Избыточное представление чисел
Определение: |
Избыточным где , | -арным представлением числа будем называть последовательность , такую что
Корневой счетчик
Корневой счетчик состоит из избыточного троичного представления числа элементов в куче и набора списочных элементов.
Значение его
-го разряда равно количеству деревьев ранга , присутствующих в куче. При таком определении избыточного корневого представления число, которое оно представляет, равно числу узлов в куче, так как толстое дерево ранга содержит ровно узлов. Заметим, что состояние избыточного корневого представления определяется неоднозначно. Очевидно, что для любой толстой кучи, состоящей из элементов, существует регулярное избыточное представление корневого счетчика. Списочный элемент, приписанный -му разряду избыточного корневого представления, — это указатель на список деревьев ранга , присутствующих в куче, образованный посредством указателей корневых узлов связываемых деревьев.Утверждение (о корневом счетчике): |
Из определения корневого счетчика следует:
|
корневой счетчик представляем расширяющимся массивом
, каждый элемент которого — запись с тремя полями:- — -й разряд равный количеству деревьев ранга .
- — прямой указатель -го разряда.
- — указатель на список деревьев ранга , присутствующих в толстой куче. Деревья в этом списке связаны при помощи указателя корневых узлов связываемых деревьев. Если в куче нет деревьев ранга , то указатель равен NULL.
Заметим, что если значение равно нулю, то нам неважно значение указателя
.Счетчик нарушений
Заметим, что счетчик нарушений очень похож на корневой счетчик выше, но в отличие от второго:
- Нас теперь интересует не само число, а только значения разрядов.
- Операция фиксации тесно связана с толстой кучей.
Значение
-го разряда для счетчика нарушений интерпретируется как количество неправильных узлов ранга , а его списочная часть — это указатели на неправильные узлы ранга .Счетчик нарушений состоит из расширенного избыточного двоичного представления и набора списочных элементов.
Счетчик нарушений представлен Саморасширяющимся массивом, элементы которого состоят из четырех полей:
- — количество неправильных узлов ранга в куче.
- — прямой указатель -го разряда
- — указатель на неправильный узел ранга
- — указатель на неправильный узел ранга
Утверждение (о счетчике нарушений): |
из определения счетчика нарушений следует:
|
Для инициализации нового звена в счетчике нарушений необходимо лишь занулить его значение в новом разряде. Делается это только тогда, когда мы вводим в кучу новое дерево ранга
. Это первый момент появления в куче узла ранга . Для тех нарушений, которые могут возникнуть в узлах ранга меньше либо равного , соответствующие разряды счетчика нарушений уже инициализированы, а узлов большего ранга в куче пока нет.Основные операции
- —
заключается в инициализации счетчиков.
- —
возвращает указатель на минимальный элемент.
- —
Чтобы выполнить эту операцию, делаем новый элемент отдельным деревом и выполняем процедуру вставки нового элемента ранга
в корневой счетчик. После этого, если необходимо, корректируем значение указателя на минимальный элемент.- —
Чтобы выполнить эту операцию, поступим следующим образом. Пусть
— узел, на который указывает указатель . Вычитаем из ключа узла . Если новый ключ меньше минимального ключа кучи , обмениваем ключ элемента с ключом минимального элемента. Новых нарушений операция не создаст. Пусть — ранг . Если — нарушаемый узел, добавляем как новое -ранговое нарушение инкрементированием -й цифры счетчика нарушений.- —
Удаляем поддерево с корнем в минимальном узле из леса. Минимальность этого элемента гарантирует нам, что среди его детей нарушений порядка кучи не было. То есть нет необходимости работать со счетчиком нарушений. Затем вставляем в кучу все деревья с корнями, расположенными в детях удаляемого узла. Очевидно, что новый минимальный ключ — либо в корне дерева леса, либо в нарушенном узле. Выполняем поиск нового минимального элемента среди корней деревьев и нарушенных узлов. Если минимальный элемент оказался в нарушенном узле, то обмениваем его с элементом, хранимым в корне этого дерева, корректируя корневой счетчик, если это необходимо. После замены новый минимум — в корне дерева леса. Этот корень будет новым минимальным узлом.
- —
выполняем
а затем- —
Первый шаг — фиксируются все нарушения в куче с меньшим максимальным рангом (разрывая связь произвольно). Не уменьшая общности, считаем, что эта куча —
. Пройти по счетчику нарушений от младшей цифры к старшей, пропуская цифры со значением . Для -й цифры делаем операцию фиксирования на каждой цифре, показываемой прямым указателем , если эта цифра имеет значение 2. Затем, если , фиксируем . Если , преобразуем это -ранговое нарушение в -ранговое нарушение, как при фиксировании, используя -рангового брата нарушенного узла вместо (несуществующего) другого -рангового нарушения. Как только не будет содержать каких-либо нарушений, нужно вставить корни из корневого счетчика в корневой счетчик инкрементированием соответствующих цифр. Если минимальный узел содержит меньший ключ, чем минимальный узел , следует установить новым минимальным узлом минимальный узел . Затем нужно вернуть модифицированную кучу в качестве результата .для освобождения кучи от нарушений достаточно выполнить следующий псевдокод:
for i:=0 to h2.MaxRank do if (CountViolation[i].Value = 2) FixCountViolation(i); for i:=0 to h2.MaxRank do if(CountViolation[i].Value = 1) IncCountViolation(i, SearchBrother(CountViolation[i].rmFirstviolation)); FixCountViolation(i);