Java的PriorityQueue的内置迭代器不会以任何特定的顺序遍历数据结构。 为什么?
这是从Java文档直接 :
这个类及其迭代器实现了Collection和Iterator接口的所有可选方法。 方法iterator()中提供的Iterator不保证以任何特定顺序遍历优先级队列的元素。 如果你需要有序的遍历,可以考虑使用Arrays.sort(pq.toArray())。
所以基本上,我的PriorityQueue工作正常,但使用它自己的内置toString()方法打印到屏幕上,导致我看到这种异常行为,并想知道是否有人可以解释为什么是迭代器提供(和使用内部)不按照自然顺序遍历PriorityQueue?
因为底层的数据结构不支持它。 二进制堆只是部分排序的,其中最小的元素是根。 当你删除它,堆是重新排序,以便下一个最小的元素是在根。 没有有效的有序遍历算法,所以没有在Java中提供。
首先猜测,它可能会按照存储顺序遍历数据。 为了尽量减少在队列中插入项目的时间,通常不会按排序顺序存储所有项目。
PriorityQueues是使用二进制堆实现的。 堆不是一个排序的结构,它是部分排序的。 每个元素都有一个与之相关的“优先级”。 使用堆实现优先级队列时,堆的根节点中将始终具有最高优先级的元素。 所以在优先级队列中,高优先级的元素在低优先级的元素之前被服务。 如果两个元素具有相同的优先级,则按照它们在队列中的顺序进行服务。 在每次删除元素后更新堆以维护堆属性
那么,就像Javadoc说的那样,它就是这样实现的。 优先级队列可能使用二进制堆作为基础数据结构。 当您删除项目时,堆被重新排序以保留堆属性。
其次,绑定特定的实现(强制排序)是不明智的。 在目前的实现中,你可以自由地以任何顺序遍历它并使用任何实现。
二进制堆是实现优先级队列的有效方式。 关于堆的订单的唯一保证是顶部的项目具有最高的优先级(根据某个顺序,可能是“最大”或“最小”)。 堆是具有以下属性的二叉树:Shape属性:树从上到下填充从左到右排序属性:任何节点上的元素比其两个子节点上的元素更大(或者,如果最小的话具有最高优先级)。 当迭代器访问所有的元素时,它可能在一个级别遍历中这样做,也就是在每个级别上依次访问每个节点,然后再进入下一个级别。 由于关于命令的唯一保证是节点比其子节点具有更高的优先级,所以每一级中的节点将没有特定的顺序。