Встроенный итератор для PriorityQueue java не пересекает структуру данных в каком-либо определенном порядке. Почему?

это прямо из Java Docs:

этот класс и его итератор реализуют все необязательные методы интерфейсов коллекции и итератора. итератор, предусмотренный в методе iterator (), не гарантирует прохождения элементов очереди приоритетов в каком-либо определенном порядке. Если вам нужен упорядоченный обход, рассмотрите возможность использования массивов.сортировка(РQ.toArray ()).

Итак, в основном, мой PriorityQueue работает нормально, но распечатка его на экран с помощью собственного встроенного метода toString () заставила меня увидеть эту аномалию в действии, и мне было интересно, может ли кто-нибудь объяснить, почему итератор, предоставленный (и используемый внутри), не пересекает PriorityQueue в своем естественном порядке?

5 ответов


потому что базовая структура данных не поддерживает его. Двоичная куча упорядочена только частично, с наименьшим элементом в корне. Когда вы удаляете это, куча переупорядочивается так, что следующий наименьший элемент находится в корне. В Java нет эффективного алгоритма упорядоченного обхода, поэтому он не предоставляется.


на первый взгляд, он, вероятно, пересекает данные в том порядке, в котором он хранится. Чтобы свести к минимуму время вставки элемента в очередь, он обычно не хранит все элементы в отсортированном порядке.


PriorityQueues реализованы с помощью двоичной кучи. Куча не является отсортированной структурой, и она частично упорядочена. Каждый элемент имеет" приоритет", связанный с ним. Использование кучи для реализации очереди приоритетов всегда будет иметь элемент наивысшего приоритета в корневом узле кучи. таким образом, в очереди приоритетов элемент с высоким приоритетом обслуживается перед элементом с низким приоритетом. Если два элемента имеют одинаковый приоритет, они обслуживаются в соответствии с их порядком в очереди. Куча обновляется после каждого удаления элементов для поддержания свойства кучи


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

во-вторых, неразумно связывать конкретную реализацию (принуждение отсортированного порядка). С текущей реализацией вы можете пройти ее в любом порядке и использовать любую реализацию.


двоичные кучи являются эффективным способом реализации очередей приоритетов. Единственная гарантия порядка, который делает куча, заключается в том, что элемент вверху имеет самый высокий приоритет (возможно, это "самый большой" или "самый маленький" в соответствии с некоторым порядком). Куча-это двоичное дерево со свойствами: Свойство Shape: дерево заполняется сверху вниз слева направо Порядок prperty: элемент на любом узле больше (или меньше, если наименьший имеет наивысший приоритет), чем два его дочерних элемента узлы. Когда итератор посещает все элементы, он, вероятно, делает это в обходе уровня, т. е. он посещает каждый узел на каждом уровне по очереди, прежде чем перейти на следующий уровень. Поскольку единственная гарантия порядка, что узел имеет более высокий приоритет, чем его дочерние узлы, Узлы на каждом уровне не будут в определенном порядке.