Java - PriorityQueue 与排序 LinkedList
哪种实现不那么“重”:PriorityQueue 还是排序的 LinkedList(使用比较器)?
我想把所有的物品都整理好。插入会非常频繁,有时我必须运行所有列表才能进行一些操作。
Which implementation is less "heavy": PriorityQueue or a sorted LinkedList (using a Comparator)?
I want to have all the items sorted. The insertion will be very frequent and ocasionally I will have to run all the list to make some operations.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
LinkedList
是最糟糕的选择。使用ArrayList
(或者更一般地,使用RandomAccess
实现者),或PriorityQueue
。如果您确实使用列表,请仅在迭代其内容之前对其进行排序,而不是在每次插入之后进行排序。需要注意的一件事是,
PriorityQueue
迭代器不按顺序提供元素;实际上,您必须删除元素(清空队列)才能按顺序迭代其元素。A
LinkedList
is the worst choice. Either use anArrayList
(or, more generally, aRandomAccess
implementor), orPriorityQueue
. If you do use a list, sort it only before iterating over its contents, not after every insert.One thing to note is that the
PriorityQueue
iterator does not provide the elements in order; you'll actually have to remove the elements (empty the queue) to iterate over its elements in order.您应该同时实现这两种方法,然后对实际数据进行性能测试,看看哪种方法最适合您的具体情况。
You should implement both and then do performance testing on actual data to see which works best in your specific circumstances.
我在这个问题上做了一个小基准。如果您希望列表在所有插入结束后进行排序,那么
PriorityQueue
和LinkedList
之间几乎没有区别(LinkedList有点更好,在我的机器上快 5% 到 10%),但是如果您使用 ArrayList,您的排序速度将比 PriorityQueue 快几乎 2 倍。在我的列表基准测试中,我测量了从开始填充值到排序结束的时间。对于 PriorityQueue - 从填充开始到轮询所有元素结束(因为元素在 PriorityQueue 中排序,同时按照 erickson 答案中提到的方式删除它们)
I have made a small benchmark on this issue. If you want your list to be sorted after the end of all insertions then there is almost no difference between
PriorityQueue
andLinkedList
(LinkedList is a bit better, from 5 to 10 percents quicker on my machine), however if you use ArrayList you will get almost 2 times quicker sorting than in PriorityQueue.In my benchmark for lists I measured time from the beginning of filling it with values till the end of sorting. For PriorityQueue - from the beginning of filling till the end of polling all elements(because elements get ordered in PriorityQueue while removing them as mentioned in erickson answer)
将对象添加到优先级队列将是 O log(n) 并且对于每个 pol 都是相同的。如果您在非常大的队列上频繁执行插入操作,那么这可能会影响性能。插入到 ArrayList 的顶部是恒定的,因此总的来说,所有这些插入在 ArrayList 上都会比在优先级队列上更快。
如果您需要按排序顺序获取所有元素,Collections.sort 总共大约需要 O n log (n) 时间。由于优先级队列中的每个 pol 将花费 O log(n) 时间,因此如果您从队列中获取所有 n 个事物,则将再次花费 O n log(n) 时间。
优先级队列获胜的用例是,如果您试图在任何给定时间查找队列中的最大值。要使用 ArrayList 做到这一点,每次您想知道最大的列表时,您都必须对整个列表进行排序。但有了优先级队列,它总是知道最大值是多少。
adding objects to the priority queue will be O log(n) and the same for each pol. If you are doing inserts frequently on very large queues then this could impact performance. Inserting into the top of an ArrayList is constant so on the whole all those inserts will go faster on the ArrayList than on the priority queue.
If you need to grab ALL the elements in sorted order the Collections.sort will work in about O n log (n) time total. Where as each pol from the priority queue will be O log(n) time, so if you grab all n things from the queue that will again be O n log (n).
The use case where priority queue wins is if you are trying to find what the biggest value in the queue is at any given time. To do that with the ArrayList you have to sort the whole list each time you want to know the biggest. But with the priority queue it always knows what the biggest value is.
如果您使用
LinkedList
,则每次添加项目时都需要重新排序这些项目,并且由于插入很频繁,我不会使用LinkedList
。因此,在这种情况下,我将使用PriorityQueue
。如果您只想将唯一元素添加到列表中,我建议使用SortedSet
(一种实现是>树集
)。If you use a
LinkedList
, you would need to resort the items each time you added one and since inserts are frequent, I wouldn't use aLinkedList
. So in this case, I would use aPriorityQueue
's If you will only be adding unique elements to the list, I recommend using aSortedSet
(one implementation is theTreeSet
).这两种数据结构之间存在根本区别,并且它们并不像您想象的那么容易互换。
根据 PriorityQueue 文档:
使用 ArrayList 并仅在迭代列表之前对其调用 Collections.sort() 。
There is a fundamental difference between the two data structures and they are not as easily interchangeable as you might think.
According to the PriorityQueue documentation:
Use an ArrayList and call Collections.sort() on it only before iterating the list.
PriorityQueue
的问题是您必须清空队列才能按顺序获取元素。如果这就是您想要的,那么这是一个不错的选择。否则,您可以使用仅在需要排序结果时才排序的ArrayList
,或者,如果项目不同(相对于比较器),则使用TreeSet
。TreeSet
和ArrayList
在空间方面都不是很“重”;哪个更快取决于用例。The issue with
PriorityQueue
is that you have to empty the queue to get the elements in order. If that is what you want then it is a fine choice. Otherwise you could use anArrayList
that you sort only when you need the sorted result or, if the items are distinct (relative to the comparator), aTreeSet
. BothTreeSet
andArrayList
are not very 'heavy' in terms of space; which is faster depends on the use case.您需要随时对其进行分类吗?如果是这种情况,您可能需要使用树集(或其他具有快速查找功能的 SortedSet)之类的东西。
如果您只是偶尔需要对其进行排序,请使用链接列表并在需要访问时对其进行排序。当您不需要访问时,将其取消排序。
Do you need it sorted at all times? If that's the case, you might want to go with something like a tree-set (or other SortedSet with a fast lookup).
If you only need it sorted occasionally, go with a linked list and sort it when you need access. Let it be unsorted when you don't need access.
java.util.PriorityQueue 是
。堆数据结构比链表更有意义
java.util.PriorityQueue
is. The heap data structure make much more sense than a linked list
我可以看到两种选择,哪一种更好取决于您是否需要能够拥有重复的项目。
如果您不需要在列表中维护重复的项目,我会使用 SortedSet(可能是 TreeSet)。
如果您需要维护重复的项目,我会使用 LinkedList 并以正确的顺序将新项目插入到列表中。
PriorityQueue 并不真正适合,除非您想在执行操作时删除项目。
与其他人一起,确保使用分析来确保为您的特定问题选择正确的解决方案。
I can see two options, which one is better depends on whether you need to be able to have duplicate items.
If you don't need to maintain duplicate items in your list, I would use a SortedSet (probably a TreeSet).
If you need maintain duplicate items, I would go with an LinkedList and insert new items into the list in the correct order.
The PriorityQueue doesn't really fit unless you want to remove the items whenever you do operations.
Going along with the others, make sure you use profiling to make sure you're picking out the correct solution for your particular problem.
恕我直言:如果有 LinkedList,我们就不需要 PriorityQueue。我可以使用 LinkedList 比使用 PriorityQueue 更快地对队列进行排序。例如,
我相信这段代码运行时间太长,因为每次我添加元素时它都会对元素进行排序。但如果我将使用下一个代码:
我认为该代码只会排序一次,并且比使用 PriorityQueue 更快。因此,我可以在使用 LinkedList 之前对它进行一次排序,无论如何,它都会运行得更快。即使它同时排序,我也确实不需要 PriorityQueue,我们真的不需要这个类。
IMHO: we don't need PriorityQueue if if have LinkedList. I can sort queue with LinkedList faster than with PriorityQueue. e.g.
I believe this code works too long, cause each time I add element it will sort elements. but if I will use next code:
I think this code will sort only once and it will be faster that using PriorityQueue. So, I can once sort my LinkedList once, before using it, in any case and it will work faster. And even if it sort the same time I don't really need PriorityQueue, we really don't need this class.