for (Event e : pq)
優先順位で繰り返されません。
while(!pq.isEmpty()){
Event e = pq.poll();
}
これは機能しますが、キューを空にします。
Javadocs から:
メソッド
iterator()
で提供されるイテレータは、特定の順序でPriorityQueueの要素を走査することを保証されていません。順序走査が必要な場合は、Arrays.sort(pq.toArray())
の使用を検討してください。
おそらく他の同等のメカニズムがあります。
基礎となる実装のために、この順序で優先度キューを通過することはできません(Javaの最小ヒープだと思います)。ソートされた配列ではないため、ある要素から優先順位の低い要素に移動できます。ピークは最小の要素を見るため、一定の時間です。次の(O(log n)時間で)を取得するには、must最小要素をデキューします。デキューは、その要素を取り出すだけの問題ではなく、要素の優先度が最も低い要素を最初に持ってくるために、基礎となる構造が再配置されます。
また、優先度キュー全体を通過するのはO(n log(n))操作です。したがって、キュー内のすべての要素を取得して並べ替えるだけでなく(O(n log(n)))、必要に応じてそれらを通過することもできます。唯一の欠点は、キューの余分なコピーを保持していることです。
それでも、この方法でデータを走査する必要がある場合、優先度キューはニーズに合ったデータ構造ではない可能性があります。
ヒープベースの優先度キューは、最初の要素が最高/最低であることのみを保証します。安価な(つまりO(n))ソートされた形式で要素を取得する方法はありません。
これを頻繁に行う必要がある場合は、要素をソートされた形式で維持する構造の使用を検討してください。たとえば、Java.util.TreeSet
を使用し、pollFirst()
/pollLast()
の代わりに peek()
またはpoll()
を使用します
以前のポスターはすべてを述べましたが、誰も完全な実例を挙げませんでした(pqをコピーする以外)。
Event[] events = pq.toArray(new Event[pq.size()]);
Arrays.sort(events, pq.comparator());
for (Event e : events) {
System.out.println(e);
}
そのため、リストでpriorityQueueを取得してからソートすることは、前述のように適切なオプションです。イテレータが予期しない結果をもたらす理由の詳細を次に示します。
反復子は、基になるデータ構造(ArrayListと同様)から出力されるため、正しい順序で要素を返しません。 ArrayListには、データがBinaryHeapのArray実装に格納されるのと同じ方法でデータが格納されます。例えば:
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]
ここで、childOf(i)は2 * i + 1および2 * i + 2であり、parentOf(i)は(i-1)/ 2です
最近、私は同じ問題を抱えていました。優先度キューの特定のオブジェクトを使用して、残りの要素を保持したいです。
1)newPriorityQueueを作成しました。 2)イテレータを使用してoldQueueのすべての要素を解析します3)oldQueue.poll()メソッドを使用して要素を取得します4)要素を挿入します3)使用しない場合はnewPriorityQueueに挿入します.
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);
}
}
最終的に、oldQueueは空になります。 @その他:-同じことができるなら、より良い方法を提案してください。正しい順序で要素を返さないため、反復子を使用できません。
peek()
メソッドはキューから何も削除しませんが、このため、IS empty。まで空の値を取得し続けます。 whileループの後は空だったため、この結論が得られました。
これを行う唯一の方法は、自分でソートすることです。次のように、元のコンパレータを取得できます。
Event[] events = Arrays.sort(pq.toArray(), pq.comparator());
for (Event e : events) {
// do stuff
}
キューのコピーを作成し、ループでポーリングできます。この例では、pqは元の優先度キューです。
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
.....
}