How to iterate over a PriorityQueue?

后端 未结 9 2051
被撕碎了的回忆
被撕碎了的回忆 2020-11-30 03:48
for (Event e : pq)

doesn\'t iterate in the priority order.

while(!pq.isEmpty()){
  Event e = pq.poll();
}

This wo

相关标签:
9条回答
  • 2020-11-30 04:26

    You can't traverse a Priority Queue in that order because of the underlying implementation (I think it's min-heap in Java).

    It's not a sorted array, so that you can just go from one element to the one with the lesser priority.

    Peeking (read the top element heap in the heap) is constant time O(1) because it looks at the smallest element.

    To get the second next one you must dequeue the smallest top element, that's how it works.
    Dequeing (re-heapify = O(log n) time) isn't just a matter of taking that element out, the underlying structure rearranges itself in order to bring the element with the least priority first.

    Also, to go through the entire priority queue to read all items in the sorted order, it is an O(n log(n)) operation.
    So you may as well just grab all the elements in the queue and sort them (also O(n log (n)) )and then you can go through them as you wish. The only disadvantage is that you're holding an extra-copy of the queue.

    Nonetheless, if you need to traverse the data in this way a priority queue may not be the right data structure for your needs.

    0 讨论(0)
  • 2020-11-30 04:39

    Recently, I had same problem. I wanted to use some particular object from the priority queue and then keep remaining elements preserved.

    1) I created a newPriorityQueue. 2) Used Iterator to parse every element in oldQueue 3) used oldQueue.poll() method to retrieve the element 4) insert the element 3) to newPriorityQueue if not used.

     Queue<String> newQueue = new PriorityQueue<String>(); 
        // Assuming that oldQueue have some data in it.
    
        Iterator<String> itr = oldQueue.iterator();
        while(itr.hasNext()){
            String str = oldQueue.poll();
            // do some processing with str
            if(strNotUsed){
                newQueue.offer(str);
            }
        }
    

    In the end, oldQueue will be empty. @ Others : - please suggest a better way if I can do the same thing. I can not use the iterator as it does not return elements in the correct order.

    0 讨论(0)
  • 2020-11-30 04:42

    You can make a copy of the queue and poll in a loop, in this example pq is the original priority queue:

    PriorityQueue<Your_class> pqCopy = new PriorityQueue<Your_class>(pq);
    while(!pqCopy.isEmpty()){
        Your_Class obj = pqCopy.poll();
        // obj is the next ordered item in the queue
        .....
    }
    
    0 讨论(0)
提交回复
热议问题