Двоичная куча — различия между версиями
Строка 5: | Строка 5: | ||
'''Двоичная куча''' или '''пирамида''' — такое двоичное дерево, для которого выполнены три условия: | '''Двоичная куча''' или '''пирамида''' — такое двоичное дерево, для которого выполнены три условия: | ||
− | * Значение в любой вершине не меньше, чем значения её потомков. | + | * Значение (ключ) в любой вершине не меньше, чем значения её потомков. |
− | * Каждый лист имеет глубину (расстояние до корня) либо d либо d-1. Иными словами, если назвать слоем совокупность вершин, находящихся на определённой глубине, то все слои, кроме, быть может, последнего, заполнены полностью. | + | * Каждый лист имеет глубину (расстояние до корня) либо <tex>d</tex> либо <tex>d-1</tex>. Иными словами, если назвать слоем совокупность вершин, находящихся на определённой глубине, то все слои, кроме, быть может, последнего, заполнены полностью. |
* Последний слой заполняется слева направо. | * Последний слой заполняется слева направо. | ||
}} | }} | ||
+ | |||
+ | |||
+ | Удобная структура данных для сортирующего дерева — массив <tex>A</tex>, у которого первый элемент, <tex>A[1]</tex> — элемент в корне, а потомками элемента <tex>A[i]</tex> являются <tex>A[2i]</tex> и <tex>A[2i+1]</tex>. Высота кучи определяется как высота двоичного дерева. То есть она равна количеству рёбер в самом длинном простом пути, соединяющем корень кучи с одним из её листьев. Высота кучи есть <tex>O(logN)</tex>, где <tex>N</tex> — количество узлов дерева. | ||
+ | |||
+ | ==Базовые процедуры== | ||
+ | |||
+ | ===Восстановление свойств кучи=== | ||
+ | |||
+ | Если в куче изменяется один из элементов, то она может перестать удовлетворять свойству упорядоченности. Для восстановления этого свойства служит процедура '''Shift_Down'''(просеивание вниз). Она восстанавливает свойство кучи в дереве, у которого левое и правое поддеревья удовлетворяют ему. Эта процедура принимает на вход массив элементов <tex>A</tex> и индекс <tex>i</tex>. Она восстанавливает свойство упорядоченности во всём поддереве, корнем которого является элемент <tex>A[i]</tex>. | ||
+ | Если <tex>i</tex>-й элемент больше, чем его сыновья, всё поддерево уже является кучей, и делать ничего не надо. В противном случае меняем местами <tex>i</tex>-й элемент с наибольшим из его сыновей, после чего выполняем '''Shift_Down''' для этого сына. | ||
+ | Процедура выполняется за время <tex>O(logN)</tex>. | ||
+ | |||
+ | <code> | ||
+ | Shift_Down(i) | ||
+ | left = 2 * i // левый сын | ||
+ | right = 2 * i + 1 // правый сын | ||
+ | // heap_size - количество элементов в куче | ||
+ | If (left ≤ A.heap_size) and (A[left] < A[i]) | ||
+ | min = left | ||
+ | else | ||
+ | min = i | ||
+ | If (right ≤ A.heap_size) and (A[right] < A[i]) | ||
+ | min = right | ||
+ | else | ||
+ | min = i | ||
+ | If (min <> i) | ||
+ | Обменять A[i] и A[largest] | ||
+ | Shift_Down(A, min) | ||
+ | </code> | ||
+ | |||
+ | ===Изменение значения элемента=== | ||
+ | |||
+ | После изменения <tex>i</tex>-ого элемента вызывается функция Shift_Up, которая просеивает | ||
+ | |||
+ | ===Извлечение минимального элемента=== | ||
+ | |||
+ | Выполняет извлечение минимального элемента из кучи за время <tex>O(logN)</tex>. | ||
+ | Извлечение выполняется в четыре этапа: | ||
+ | # Значение корневого элемента (он и является минимальным) сохраняется для последующего возврата. | ||
+ | # Последний элемент копируется в корень, после чего удаляется из кучи. | ||
+ | # Вызывается '''Shift_Down''' для корня. | ||
+ | # Сохранённый элемент возвращается. | ||
+ | <code> | ||
+ | extract_min() | ||
+ | min = A[1] | ||
+ | A[1] = A[A.heap_size] | ||
+ | A.heap_size = A.heap_size - 1 | ||
+ | Shift_Down(A, 1) | ||
+ | return min | ||
+ | </code> | ||
+ | |||
+ | ===Добавление нового элемента=== | ||
+ | |||
+ | Элемент добавляется в конец кучи |
Версия 06:23, 15 марта 2011
Эта статья находится в разработке!
Определение: |
Двоичная куча или пирамида — такое двоичное дерево, для которого выполнены три условия:
|
Удобная структура данных для сортирующего дерева — массив
, у которого первый элемент, — элемент в корне, а потомками элемента являются и . Высота кучи определяется как высота двоичного дерева. То есть она равна количеству рёбер в самом длинном простом пути, соединяющем корень кучи с одним из её листьев. Высота кучи есть , где — количество узлов дерева.Содержание
Базовые процедуры
Восстановление свойств кучи
Если в куче изменяется один из элементов, то она может перестать удовлетворять свойству упорядоченности. Для восстановления этого свойства служит процедура Shift_Down(просеивание вниз). Она восстанавливает свойство кучи в дереве, у которого левое и правое поддеревья удовлетворяют ему. Эта процедура принимает на вход массив элементов
и индекс . Она восстанавливает свойство упорядоченности во всём поддереве, корнем которого является элемент . Если -й элемент больше, чем его сыновья, всё поддерево уже является кучей, и делать ничего не надо. В противном случае меняем местами -й элемент с наибольшим из его сыновей, после чего выполняем Shift_Down для этого сына. Процедура выполняется за время .
Shift_Down(i)
left = 2 * i // левый сын right = 2 * i + 1 // правый сын // heap_size - количество элементов в куче If (left ≤ A.heap_size) and (A[left] < A[i]) min = left else min = i If (right ≤ A.heap_size) and (A[right] < A[i]) min = right else min = i If (min <> i) Обменять A[i] и A[largest] Shift_Down(A, min)
Изменение значения элемента
После изменения
-ого элемента вызывается функция Shift_Up, которая просеиваетИзвлечение минимального элемента
Выполняет извлечение минимального элемента из кучи за время
. Извлечение выполняется в четыре этапа:- Значение корневого элемента (он и является минимальным) сохраняется для последующего возврата.
- Последний элемент копируется в корень, после чего удаляется из кучи.
- Вызывается Shift_Down для корня.
- Сохранённый элемент возвращается.
extract_min()
min = A[1] A[1] = A[A.heap_size] A.heap_size = A.heap_size - 1 Shift_Down(A, 1) return min
Добавление нового элемента
Элемент добавляется в конец кучи