Часть VII : Heap
Значение в любой вершине не меньше, чем значения её потомков.
Глубина листьев (расстояние до корня) отличается не более чем на 1 слой.
Последний слой заполняется слева направо.
length(A) – количество элементов массива
heap_size(A) – количество элементов пирамиды, содержащихся в массиве
heap_size(A) length(A)
Если Ai – промежуточный узел дерева, то для него:
индекс родительского узла parent(i) = i / 2
индекс левого дочернего узла left(i) = 2i
индекс правого дочернего узла right(i) = 2i + 1
невозрастающие – max-heap property: Aparent(i) Ai пирамидальные сортировки
неубывающие – min-heap property: Aparent(i) Ai очереди с приоритетами
Heapify(A, i)
left = 2i
right = 2i+1
heap_size - количество элементов в куче
if left ≤ A.heap_size и A[left] > A[i]
then largest = left
else largest = i
if right ≤ A.heap_size и A[right] > A[largest]
then largest = right
if largest ≠ i
then Обменять A[i] ↔ A[largest]
Heapify(A, largest)
Build-Heap(A)
A.heap_size ← A.length
for i ← ⌊A.length/2⌋ downto 1
do Heapify(A, i)
sort
Heapsort(A)
Build_Max_Heap(A)
for i ← A.length downto 1
do Обменять A[1] ↔ A[i]
A.heap_size ← A.heap_size-1
Heapify(A,1)
Edit
Heap_Increase_Key(A, i, key)
if key < A[i]
then error "Новый ключ меньше предыдущего"
A[i] ← key
while i > 1 и A[⌊i/2⌋] < A[i]
do Обменять A[i] ↔ A[⌊i/2⌋]
i ← ⌊i/2⌋
insert
Heap_Insert(A, key)
A.heap_size ← A.heap_size+1
A[A.heap_size] ← -∞
Heap_Increase_Key(A, A.heap_size, key)
Max
Heap_Extract_Max(A)
if A.heap_size[A] < 1
then error "Куча пуста"
max ← A[1]
A[1] ← A[A.heap_size]
A.heap_size ← A.heap_size-1
Heapify(A, 1)
return max
Часть VIII : Skip-List
списки с пропусками: вероятностная структура данных; альтернатива сбалансированным деревьям
p = ½ Уровень элемента списка ограничен некоторым значением MaxLevel
Заголовок Skip Lists – содержит уровень списка и массив из MaxLevel указателей
Указатели заголовка списка для уровней, превышающих текущий уровень списка, указывают на специальный элемент EList
Уровень элемента генерируется случайным образом независимо от количества элементов в Skip List
struct Item { … }; – элемент списка в Skip Lists
struct SkipLists {
int level; – текущий уровень списка
struct Item *header; – указатель на головной элемент
};
Level()
level = 1
while random() < p и level < MaxLevel
level = level + 1
search
x = list->header – указатель на первый элемент верхнего уровня
цикл по i от list->level – 1 до 0 {
while x->forward[i]->key < k
x = x->forward[i]
}
x = x->forward[0]
if x->key = k успех: x else отказ
insert
цикл по i от list->level – 1 до 0 {
while x->forward[i]->key < k
x = x->forward[i]
update[i] = x – позиция предшествующего элемента i-го уровня
}
x = x->forward[0] – элемент, перед которым нужно вставить новый
if x->key = k
отказ
level = Level()
if list->level < level {
добавить в элементы update[i] значения list->header
list->level = level
}
для всех i от 0 до level – 1 {
x->forward[i] = update[i]->forward[i]
update[i]->forward[i] = x
}
DELETE
Как в insert только update[i]->forward[i] = x->forward[i]