How to iterate over a PriorityQueue?

后端 未结 9 2050
被撕碎了的回忆
被撕碎了的回忆 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:17

    A heap based priority queue only guarantees that the first element is the highest/lowest. There is no cheap (i.e. O(n)) way to get the elements in sorted form.

    If you need to do this often, consider using a structure that maintains the elements in sorted form. For example, use java.util.TreeSet, and use either pollFirst() or pollLast() in place of peek() / poll()

    0 讨论(0)
  • 2020-11-30 04:17
    for (Event event: pq.toArray(new Event[pq.size()])) {
        event.toString();
    }
    
    0 讨论(0)
  • 2020-11-30 04:19

    Previous posters said everything but noone gave full working example (other than copying pq), so here it is:

    Event[] events = pq.toArray(new Event[pq.size()]);
    Arrays.sort(events, pq.comparator());
    for (Event e : events) {
        System.out.println(e);
    }
    
    0 讨论(0)
  • 2020-11-30 04:22

    The peek() method does not remove anything from the queue, but because of this, it will continually get the top value until it IS empty. I'm guessing you checked if it was empty after your while loop, which would give you this conclusion.

    The only way to do this is to sort it yourself. You can get the original comparator for it like this:

    Event[] events = Arrays.sort(pq.toArray(), pq.comparator());
    for (Event e : events) {
        // do stuff
    }
    
    0 讨论(0)
  • 2020-11-30 04:25

    From the Javadocs

    The Iterator provided in method iterator() is not guaranteed to traverse the elements of the PriorityQueue in any particular order. If you need ordered traversal, consider using Arrays.sort(pq.toArray()).

    There are probably other equivalent mechanisms.

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

    So taking the priorityQueue in a List and then sorting it is a good option as mentioned above. Here are some details why the iterator gives unexpected results:

    The iterator does not return elements in the correct order because it prints from the underlying data structure (similar to ArrayList). The ArrayList has data stored in it in the same way the data is stored in an Array implementation of BinaryHeap. For example:

    PriorityQueue<Integer> pq = new PriorityQueue<>();
    ArrayList<Integer> test = new ArrayList(Arrays.asList(6,12,7,9,2));
    test.forEach(x -> pq.add(x)); 
    System.out.println("Priority Queue:- "+pq); [2, 6, 7, 12, 9]
    

    where childOf(i) is 2*i+1 and 2*i+2 and parentOf(i) is (i-1)/2

    0 讨论(0)
提交回复
热议问题