24 июля 2023 г. (изменено: 24 июля 2023 г.)

Канал: @cherkashindev

711

Бинарная куча и приоритетная очередь

Последние пару месяцев я решил попрактиковаться в решении задач на алгоритмы и структуры данных и вспомнить всё, что мы проходили в универе. Там, кстати, ни слова не было не только о сложностях алгоритмов, но и о Приоритетных очередях.

❓ Что это такое “Приоритетная очередь”

Приоритетная очередь — это коллекция, в которой, в отличии от обычной очереди, элементы упорядочиваются не на основе того, когда был добавлен элемент, а на основе приоритета, который этот элемент имеет. То есть, первым всегда будет извлекаться элемент с максимальным приоритетом. Также можно настроить очередь, чтобы она работала с наименьшими приоритетами.

Приоритетная очередь поддерживает те же операции, что и обычная очередь.

❓ Что это такое “Бинарная (двоичная) куча”

Бинарная куча – структура данных, позволяющая быстро (за логарифмическое время) добавлять элементы и извлекать элемент с максимальным приоритетом.

Куча представляет собой полное бинарное дерево, в котором каждый элемент не меньше своих потомков. Таким образом, максимальный элемент всегда находится в корне, поэтому доступ к нему происходит за O(1).

Можно сказать, что приоритетная очередь — это интерфейс, а бинарная куча — одна из возможных реализаций интерфейса “приоритетной очереди”.

💡 О том, как происходит добавление и удаление элементов из бинарной кучи описано в статье на хабре Структуры данных: двоичная куча (binary heap)

🧑‍💻 Собеседования

Интересный факт, что при прохождении собеседования на вашем языке программирования такая структура данных может отсутствовать.

Например:

  • В .NET 6 появилась встроенная реализация приоритетной очереди, она так и называется PriorityQueue
  • А вот в JavaScript из коробки в нет подобной реализации

В таком случае можно быстро реализовать приоритетную очередь с помощью динамического массива:

  • Описать класс PriorityQueue, у которого под капотом используется динамический массив
  • Метод Enqueue — добавляет элемент в конец динамического массива
  • Метод Dequeue — извлекает элемент с наименьшим приоритетом

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

⌨️ Пример задачи с Leetcode

Чтобы понять как и зачем использовать приоритетную очередь можно порешать следующие задачи на Leetcode

  1. Top K Frequent Words
  2. Top K Frequent Elements

Еще по теме:

🔥 4