Двоичная куча — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
Строка 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

Эта статья находится в разработке!


Определение:
Двоичная куча или пирамида — такое двоичное дерево, для которого выполнены три условия:
  • Значение (ключ) в любой вершине не меньше, чем значения её потомков.
  • Каждый лист имеет глубину (расстояние до корня) либо [math]d[/math] либо [math]d-1[/math]. Иными словами, если назвать слоем совокупность вершин, находящихся на определённой глубине, то все слои, кроме, быть может, последнего, заполнены полностью.
  • Последний слой заполняется слева направо.


Удобная структура данных для сортирующего дерева — массив [math]A[/math], у которого первый элемент, [math]A[1][/math] — элемент в корне, а потомками элемента [math]A[i][/math] являются [math]A[2i][/math] и [math]A[2i+1][/math]. Высота кучи определяется как высота двоичного дерева. То есть она равна количеству рёбер в самом длинном простом пути, соединяющем корень кучи с одним из её листьев. Высота кучи есть [math]O(logN)[/math], где [math]N[/math] — количество узлов дерева.

Базовые процедуры

Восстановление свойств кучи

Если в куче изменяется один из элементов, то она может перестать удовлетворять свойству упорядоченности. Для восстановления этого свойства служит процедура Shift_Down(просеивание вниз). Она восстанавливает свойство кучи в дереве, у которого левое и правое поддеревья удовлетворяют ему. Эта процедура принимает на вход массив элементов [math]A[/math] и индекс [math]i[/math]. Она восстанавливает свойство упорядоченности во всём поддереве, корнем которого является элемент [math]A[i][/math]. Если [math]i[/math]-й элемент больше, чем его сыновья, всё поддерево уже является кучей, и делать ничего не надо. В противном случае меняем местами [math]i[/math]-й элемент с наибольшим из его сыновей, после чего выполняем Shift_Down для этого сына. Процедура выполняется за время [math]O(logN)[/math].

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)

Изменение значения элемента

После изменения [math]i[/math]-ого элемента вызывается функция Shift_Up, которая просеивает

Извлечение минимального элемента

Выполняет извлечение минимального элемента из кучи за время [math]O(logN)[/math]. Извлечение выполняется в четыре этапа:

  1. Значение корневого элемента (он и является минимальным) сохраняется для последующего возврата.
  2. Последний элемент копируется в корень, после чего удаляется из кучи.
  3. Вызывается Shift_Down для корня.
  4. Сохранённый элемент возвращается.

extract_min()

 min = A[1]
 A[1] = A[A.heap_size]
 A.heap_size = A.heap_size - 1
 Shift_Down(A, 1)
 return min

Добавление нового элемента

Элемент добавляется в конец кучи