на стр 6, лекции 3, Очевидно "Ck <= модуль(Gk(е))*b(k+1)" (1) - , подскажите что значит "модуль" и почему это очевидно... |
Толстые кучи
Толстая куча
Толстая куча — это почти кучеобразный нагруженный лес.
Представление толстой кучи. Каждый узел толстой кучи будем представлять записью следующего вида:











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





Корневой счетчик. Корневой счетчик состоит из избыточного троичного представления числа элементов в куче и набора списочных элементов.
Значение -го разряда избыточного корневого представления равно
количеству деревьев ранга
, присутствующих в куче. При таком
определении избыточного корневого представления число, которое оно
представляет, равно числу узлов в куче, так как толстое дерево
ранга
содержит ровно
узлов. Заметим, что
состояние избыточного корневого представления определяется неоднозначно. Отсюда следует, что
толстая куча с одним и тем же набором элементов может быть представлена
различными наборами толстых деревьев. Очевидно, что для любой толстой
кучи, состоящей из
элементов, существует регулярное избыточное
представление корневого счетчика.
Списочный элемент, приписанный -му разряду избыточного
корневого представления, — это указатель на список деревьев ранга
,
присутствующих в куче, образованный посредством указателей
корневых узлов связываемых деревьев.
Определение корневого счетчика дает возможность сделать несколько утверждений:
- Корневой счетчик позволяет иметь доступ к корню любого
дерева ранга
за время
.
- Вставка толстого дерева ранга
соответствует операции инкрементирования
-го разряда корневого счетчика.
- Удаление толстого поддерева ранга
соответствует операции декрементирования
-го разряда корневого счетчика.
- Операции инкрементирования и декрементирования
-го разряда корневого счетчика осуществляются за время
.
Представление корневого счетчика. Корневой счетчик
представляем расширяющимся массивом ,
каждый элемент которого — запись с тремя полями:

-
—
-й разряд, равный количеству деревьев ранга
;
-
— прямой указатель
-го разряда;
-
— указатель на список деревьев ранга
, присутствующих в толстой куче. Деревья в этом списке связаны при помощи указателя
корневых узлов связываемых деревьев. Если в куче нет деревьев ранга
, то указатель
заземлен. Заметим, что если значение
равно нулю, то нам неважно, каково значение указателя
.
Инициализация корневого счетчика (InitRootCount). Поскольку
корневой счетчик реализован как массив записей, возникает вопрос о
величине данного массива и о том, что делать, когда весь этот массив
заполнен. Чтобы была возможность оценить время инициализации счетчиков
величиной , используем поразрядную их инициализацию. То есть
будем добавлять новые разряды только тогда, когда возникает такая
необходимость, и при этом инициализировать новый разряд сразу в обоих
счетчиках. Для этого мы вводим переменную
, которая
показывает нам, какая часть массивов счетчиков используется в данный
момент.
При начальной инициализации необходимо установить счетчики в состояние, которое отвечает пустой куче. Очевидно, что в пустой куче не может быть никаких нарушений. Операция инициализации выглядит следующим образом.
Обновление прямого указателя i-го разряда корневого счетчика заключается в выполнении операторов
![\formula{
\t If\ ({\rm RootCount}[i+1].{\rm
Value} = 3-1)\\
\mbox{}\q \t then\ {\rm
RootCount}[i].{\rm ForwardPointer} :=
{\rm RootCount}[i+1].{\rm ForwardPointer}\\
\mbox{}\q \t else\
\t{RootCount}[i].\t{ForwardPointer}:= i+1;
}](/sites/default/files/tex_cache/ef11a1f0ee1caa115d7d95612efe9366.png)
Корректировка списочной части i-го разряда корневого счетчика
при вставке в кучу нового дерева ранга i .
Эта процедура вставляет новое дерево ранга
(на него указывает указатель
) в списочную часть
-го
разряда корневого счетчика
и заключается
в выполнении операторов
![\formula{
p1 := {\rm RootCount}[i].{\rm ListPointer};\\
\t if\ ({\rm RootCount}[i].{\rm Value}
\ne 0)\
\t then\ p\t{\^{}.}{\rm Right} := p1\
\t {else}\
p\t{\^{}}.{\rm Right} := {\rm nil};\\
p\t{\^{}.}{\rm Left}:= {\rm nil}; {\rm RootCount}[i].{\rm ListPointer} := p;
}](/sites/default/files/tex_cache/dc65650e87612a2e2b865988f9582f9b.png)
Корректировка списочной части i>-го разряда
корневого счетчика при удалении из кучи дерева
ранга i . Эта процедура удаляет дерево
ранга
(на него указывает указатель
) из списочной
части
-го разряда корневого счетчика
.
Будем считать, что указанное дерево присутствует в куче. Процедура заключается в выполнении
операторов
![\formula{
p1:= {\rm RootCount}[i].{\rm ListPointer};\\
\t If\ (p1 = p)\ \t then\
{\rm RootCount}[i].{\rm ListPointer} := p\t{\^{}}.{\rm Right};\\
j:= 1;\\
\t while\ (j \le {\rm
RootCount}[i].{\rm Value})\ \t{and}\
(p1\t{\^{}}.{\rm Right} \ne p)\ \t do\\
\t begin\ j:= j+1;\ p1 :=
p1\t{\^{}.}{\rm Right}\,{\rm End}; \\
p1\t{\^{}.}{\rm Right} := p\t{\^{}}.{\rm Right};
}](/sites/default/files/tex_cache/451bc8c1d53c1f1c3d5862f5edacda42.png)
Связывание (Fastening (p1, p2,
p3)) трех толстых деревьев ранга i в одно толстое
дерево ранга i +1. Эта функция принимает три указателя на три разных толстых дерева одного и того же
ранга
и возвращает указатель на вновь сформированное
дерево ранга
.