Все разделы
Выбрать школу

Школа. Увлечения. Большое будущее.

PROSCHOOLS · ОБРАЗОВАНИЕ РЯДОМ

Ваш город

Выберите город, чтобы находить образование и возможности рядом.

Как учитываем городКаталог и кнопки «Выбрать школу» покажут школы выбранного города.Онлайн-курсы, учебник, ГДЗ и задания к экзаменам доступны по всей России.

Популярные города

Будет выбран: Вся Россия

Учебные материалы останутся прежними.

Поиск по сайту

По всему сайтуШколы выбранного города — выше в результатах

С чего начнём?

↑ ↓ — выбрать результат · Enter — открыть · Esc — закрыть

Куча heap: быстрый минимум и очередь с приоритетами

💻 Информатика · 10 класс

Свойство двоичной кучи, индексы в массиве, подъём и спуск элемента на примере heapq.

Клавиатура в компьютерном классе
Иллюстрация к предмету «Информатика»Hmartil · Wikimedia Commons · CC BY-SA 4.0

Что называется кучей

Двоичная куча — структура данных для быстрого доступа к минимуму или максимуму. Здесь рассматриваем min-heap: значение родителя не больше значений его детей. Наименьший элемент находится в корне. В max-heap неравенство обратное, в корне расположен максимум.

Это значение слова heap не следует путать с областью динамической памяти программы. Куча как структура описывает организацию элементов, а не место, где операционная система выделила память.

Форма дерева и индексы

Уровни двоичного дерева заполняются сверху вниз, слева направо. Такую форму удобно хранить в массиве. При нумерации с нуля дети элемента i имеют индексы 2i+1 и 2i+2, если существуют, а родитель некорневого элемента — (i−1)//2.

Массив [2,5,3,9,7] задаёт корректную min-heap:2 не больше 5 и 3, а 5 не больше 9 и 7. Но весь массив не отсортирован:5 стоит перед 3. Свойство кучи сравнивает родителей с детьми, а не любые соседние позиции.

Как поддерживается свойство

При добавлении элемент сначала помещают в конец, сохраняя форму дерева. Если он меньше родителя, их меняют местами и продолжают подъём. Путь до корня содержит порядка log₂n уровней.

При извлечении минимума запоминают корень и переносят на его место последний элемент. Затем спускают его, выбирая меньшего из существующих детей. Отдельно учитывают один оставшийся ребёнок и пустую кучу. Перестановка с произвольным ребёнком может нарушить свойство.

Пример Python

import heapq

heap = [9, 2, 7, 5]
heapq.heapify(heap)
heapq.heappush(heap, 3)
print(heap[0])
print(heapq.heappop(heap))
print(heapq.heappop(heap))

Вывод:2,2,3 на отдельных строках. Первое обращение только читает минимум. Первый heappop удаляет 2, поэтому следующим минимумом становится 3. Heapify преобразует список на месте; его результат не нужно присваивать обратно как новый список.

Сложность и назначение

Доступ к корню занимает O(1), добавление и извлечение — O(log n), построение через heapify — O(n). Полная сортировка последовательными извлечениями занимает O(n log n). Обычная куча не обеспечивает мгновенного поиска любого заданного значения.

Очередь с приоритетами выдаёт элемент по приоритету, а не обязательно по времени добавления. Например, можно хранить пары «числовой приоритет, задача». При равных приоритетах нужно заранее определить порядок и убедиться, что сравниваемые поля поддерживают сравнение.

Границы

Нельзя произвольно менять элемент внутри списка и считать, что свойство сохранилось. Нельзя вызывать heappop у пустой кучи без обработки ситуации: Python выбросит IndexError. Прикладной код должен определить, что означает отсутствие задач.

Практика

  1. Корректна ли min-heap [1,4,2,6]?
  2. Какие индексы детей у элемента 2 при нумерации с нуля?
  3. Удаляет ли heap[0] минимум?

Ответы

1. Да:1≤4,1≤2,4≤6. 2. 5 и 6, если они существуют. 3. Нет: это только чтение. Для удаления используют heappop, который также восстанавливает структуру. Не путайте свойство кучи с полной сортировкой списка.

Связанные материалы

Источники и материалы