Автор оригинала: Pankaj Kumar.
Время от времени нам нужно обрабатывать элементы очереди в определенном порядке. Очередь приоритетов-это структура данных, которая выполняет эту работу. Очередь приоритетов Java отличается от “обычной” очереди . Вместо “Первым вошел-Первым вышел” он извлекает элементы в порядке их приоритета.
Приоритетная очередь Java
Файл java.util.Класс PriorityQueue
предоставляет нам реализацию такого типа данных, используя внутреннюю реализацию кучи приоритетов. Приоритетная очередь Java – это неограниченная очередь. Он был представлен в Java 1.5 и улучшен в выпуске Java SE 8. Очередь приоритетов внутренне реализована с помощью следующей структуры данных “Приоритетная куча”.
Вот иерархия классов PriorityQueue:
Диаграмма классов приоритетной очереди:
Конструкторы очереди приоритетов Java
- Приоритетная очередь() – Создает приоритетную очередь с начальной емкостью по умолчанию, т. е. 11
- Приоритетная очередь(коллекция c) – Создает приоритетную очередь с элементами в указанной коллекции
- Приоритетная очередь(int initialCapacity) – Создает приоритетную очередь с указанной начальной емкостью
- Приоритетная очередь(int initialCapacity, Компаратор компаратор) – Создает приоритетную очередь с предоставленной начальной емкостью, и порядок ее элементов соответствует указанному компаратору
- Приоритетная очередь(приоритетная очередь c) – Создает приоритетную очередь, содержащую элементы в указанной очереди приоритетов
- Приоритетная очередь(сортированный набор c) – Создает приоритетную очередь, содержащую элементы в указанном отсортированном наборе
Элементы очереди приоритетов упорядочены по их естественному порядку, если только мы не предоставим Компаратор
при его создании. По умолчанию элементы упорядочены в порядке возрастания, поэтому во главе очереди находится элемент с наименьшим приоритетом.
Если есть два элемента, которые имеют право стать главой одновременно, такого рода связи разрываются произвольно.
Пример приоритетной очереди Java
Давайте создадим Приоритетную очередь
, содержащую различные задачи:
PriorityQueue tasks=new PriorityQueue(); tasks.add("task1"); tasks.add("task4"); tasks.add("task3"); tasks.add("task2"); tasks.add("task5");
Это создает приоритетную очередь задач, которая будет упорядочена естественным порядком Строка
. Давайте создадим другую приоритетную очередь, которая упорядочивает задачи в порядке, обратном естественному порядку. Поэтому нам нужно передать компаратор:
PriorityQueue reverseTasks=new PriorityQueue(Comparator.reverseOrder()); reverseTasks.add("task1"); reverseTasks.add("task4"); reverseTasks.add("task3"); reverseTasks.add("task2"); reverseTasks.add("task5");
Методы очереди приоритетов Java
Теперь давайте рассмотрим все методы, доступные для приоритетной очереди, и используем их:
- Логическое добавление(E e) – Этот метод вставляет указанный элемент в очередь. Мы уже добавили 5 задач в нашу очередь, используя этот метод.
Компаратор comparator() – Этот метод возвращает компаратор, используемый для упорядочения элементов в этой очереди. Он возвращает значение null, если не был указан компаратор и очередь отсортирована в соответствии с естественным порядком ее элементов. Итак, если мы сделаем:
Результатом будет:
логическое значение содержит(объект o) – Возвращает значение true, если очередь содержит указанный элемент. Давайте проверим, относится ли “задача 3” к приоритетным задачам очереди:
Это печатает:
- логическое предложение(E e) – Как и метод add (), этот метод также добавляет элемент в очередь. Методы offer() и add() на самом деле немного отличаются для очередей с ограниченной емкостью, но в случае очереди с приоритетом оба они одинаковы. В отличие от add(), функция offer() не создает исключения, даже если не удается добавить элемент в очередь.
E peek() – Извлекает заголовок этой очереди или возвращает значение null, если эта очередь пуста. Другими словами, он возвращает элемент с наивысшим приоритетом. Итак, следующий код:
Дает нам:
E poll() – Этот метод также извлекает заголовок очереди(элемент с наивысшим приоритетом) или возвращает значение null, если очередь пуста. Но в отличие от peek(), он также удаляет элемент. Итак, если мы вызовем poll():
А потом заглянуть:
У нас будет следующий результат:
- int size() – Возвращает количество элементов в очереди.
- логическое удаление(Объект o) – Удаляет указанный элемент из очереди, если он присутствует. Если присутствуют два одинаковых элемента, он удаляет только один из них.
- Объект[] toArray() – Возвращает массив, содержащий все элементы в очереди.
- T[] toArray(T[] a) – Возвращает массив, содержащий все элементы в очереди, и тип возвращаемого массива соответствует типу указанного массива.
- Итератор итератор() – Возвращает итератор для очереди.
- void clear() – Удаляет все элементы из очереди.
Помимо этого, Приоритетная очередь
также наследует методы из Коллекции
и Объектов
классов.
Сложность Времени Очереди с приоритетом Java
- Для методов запроса и удаления запросов временная сложность составляет O(log(n))
- Для методов remove(объект) и contains(Объект) временная сложность линейна
- Для методов поиска он имеет постоянную временную сложность
Эта реализация очереди приоритетов не является потокобезопасной. Итак, если нам нужен синхронизированный доступ, нам нужно использовать PriorityBlockingQueue .
Ссылка: API Doc