Eğitim Portalı/Java/PriorityQueue ve ArrayDeque
Java01-java/52-priorityqueue-ve-arraydeque

PriorityQueue ve ArrayDeque

Bazı problemler "sıradaki elemanı" özel bir kurala göre ister: ya uçlardan (baş/son) erişim (yığın, kuyruk) ya da önceliğe göre erişim. Java bu iki ihtiyaca iki güçlü sınıfla yanıt verir: çift uçlu kuyruk ArrayDeque v…

PriorityQueue ve ArrayDeque

Bazı problemler "sıradaki elemanı" özel bir kurala göre ister: ya uçlardan (baş/son) erişim (yığın, kuyruk) ya da önceliğe göre erişim. Java bu iki ihtiyaca iki güçlü sınıfla yanıt verir: çift uçlu kuyruk ArrayDeque ve öncelik kuyruğu PriorityQueue. İkisi de Queue arayüzünü uygular ama tamamen farklı işler için tasarlanmıştır.

ArrayDeque: yığın ve kuyruk

ArrayDeque (array deque = çift uçlu kuyruk), her iki uçtan da O(1) ekleme/çıkarma yapar. Tek sınıfla hem yığın hem kuyruk kurarsın:

// Yığın (LIFO) — son giren ilk çıkar
deque.push(x);  deque.pop();  deque.peek();

// Kuyruk (FIFO) — ilk giren ilk çıkar
deque.offer(x); deque.poll(); deque.peek();

// Çift uçlu
deque.addFirst(x); deque.addLast(x); deque.peekFirst(); deque.peekLast();

Örnek 1 (./Ornek1.java) ArrayDeque'i yığın, kuyruk ve çift uçlu olarak kullanır.

Neden ArrayDeque?

  • Yığın için: Eski Stack sınıfı Vector tabanlıdır (senkronize, yavaş, eski). Modern Java'da yığın gerekiyorsa ArrayDeque önerilir.
  • Kuyruk için: LinkedList de Queue'dur ama ArrayDeque daha hızlı ve az bellek kullanır (dizi tabanlı, önbellek dostu).
  • Dikkat: null eleman kabul etmez (null, "eleman yok" sinyaliyle karışmasın diye).

PriorityQueue: öncelik kuyruğu

PriorityQueue, elemanları ekleme sırasına göre değil, önceliğe göre verir. İçte bir heap (yığın ağacı) tutar; peek/poll her zaman en öncelikli elemanı döndürür:

PriorityQueue<Integer> pq = new PriorityQueue<>();        // min-heap (en küçük önce)
PriorityQueue<Integer> max = new PriorityQueue<>(Comparator.reverseOrder()); // max-heap
PriorityQueue<Gorev> sch = new PriorityQueue<>(Comparator.comparingInt(Gorev::oncelik));

Maliyetler: add/poll O(log n), peek O(1). Örnek 2 (./Ornek2.java) min-heap, max-heap ve gerçek bir görev zamanlayıcı (en acil iş önce) gösterir.

Kullanım alanları: görev/iş zamanlama, Dijkstra/A* gibi graf algoritmaları, "en yakın/en büyük K eleman" problemleri, olay simülasyonu.

Önemli: PriorityQueue'yu for-each/iterator ile gezmek sıralı sonuç vermez — sıra yalnızca poll ile birer birer çıkarınca ortaya çıkar. Tümünü sıralı istiyorsan ya hepsini poll et ya da bir listeye alıp sort uygula.

Karşılaştırma

SınıfErişim kuralıTipik kullanım
ArrayDeque (yığın)LIFO (son giren ilk çıkar)Geri-al, ifade ayrıştırma, DFS
ArrayDeque (kuyruk)FIFO (ilk giren ilk çıkar)İş kuyruğu, BFS
PriorityQueueÖnceliğe göreZamanlayıcı, Dijkstra, top-K

Özet

İki uç-erişim koleksiyonunu öğrendik: her iki uçtan hızlı erişen ve modern yığın/kuyruk seçimi olan ArrayDeque (Örnek 1) ile elemanları önceliğe göre veren heap tabanlı PriorityQueue (Örnek 2). "Yığın/kuyruk → ArrayDeque, önceliğe göre → PriorityQueue" kuralını benimse. Sırada, metni verimli biçimde inşa etmenin yolu: StringBuilder.

Kod Örnekleri(2)

Ornek1

çalıştırılabilir
Ornek1.java
1// Ornek1: ArrayDeque — hem yığın (stack) hem kuyruk (queue) için hızlı çift uçlu yapı.
2// Çalıştırma: java Ornek1.java
3import java.util.ArrayDeque;
4import java.util.Deque;
5
6public class Ornek1 {
7
8    public static void main(String[] args) {
9        // YIĞIN (LIFO) olarak: push/pop/peek. (Eski Stack sınıfının yerine ÖNERİLEN.)
10        Deque<String> yigin = new ArrayDeque<>();
11        yigin.push("sayfa1"); yigin.push("sayfa2"); yigin.push("sayfa3");
12        System.out.println("Yığın: " + yigin);
13        System.out.println("pop (geri): " + yigin.pop() + " -> " + yigin); // son giren ilk çıkar
14        System.out.println("peek (tepe): " + yigin.peek());
15
16        // KUYRUK (FIFO) olarak: offer/poll/peek.
17        Deque<String> kuyruk = new ArrayDeque<>();
18        kuyruk.offer("müşteri1"); kuyruk.offer("müşteri2"); kuyruk.offer("müşteri3");
19        System.out.println("\nKuyruk: " + kuyruk);
20        System.out.println("poll (ilk): " + kuyruk.poll() + " -> " + kuyruk); // ilk giren ilk çıkar
21
22        // ÇİFT UÇLU: iki uçtan da ekle/çıkar.
23        Deque<Integer> deque = new ArrayDeque<>();
24        deque.addFirst(1); deque.addLast(2); deque.addFirst(0);
25        System.out.println("\nDeque (çift uçlu): " + deque);
26        System.out.println("ilk=" + deque.peekFirst() + ", son=" + deque.peekLast());
27
28        System.out.println("""
29
30                --- ArrayDeque ---
31                Çift uçlu kuyruk (double-ended queue): her iki uçtan ekle/çıkar O(1).
32                Yığın olarak: push/pop/peek (LIFO). Kuyruk olarak: offer/poll/peek (FIFO).
33                NEDEN ArrayDeque? Eski Stack (Vector tabanlı, senkronize, yavaş) yerine ÖNERİLİR;
34                LinkedList'e göre de daha hızlı ve az bellek kullanır. null eleman KABUL ETMEZ.""");
35    }
36}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.

Ornek2

çalıştırılabilir
Ornek2.java
1// Ornek2: PriorityQueue — öncelik kuyruğu (heap). En öncelikli eleman önce çıkar.
2// Çalıştırma: java Ornek2.java
3import java.util.Comparator;
4import java.util.PriorityQueue;
5
6public class Ornek2 {
7
8    record Gorev(String ad, int oncelik) {}
9
10    public static void main(String[] args) {
11        // Varsayılan: min-heap (en KÜÇÜK önce çıkar).
12        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
13        minHeap.add(50); minHeap.add(10); minHeap.add(30); minHeap.add(20);
14        System.out.print("Min-heap çıkış sırası: ");
15        while (!minHeap.isEmpty()) System.out.print(minHeap.poll() + " "); // 10 20 30 50
16        System.out.println();
17
18        // Max-heap: Comparator ile ters (en BÜYÜK önce).
19        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
20        maxHeap.addAll(java.util.List.of(50, 10, 30, 20));
21        System.out.print("Max-heap çıkış sırası: ");
22        while (!maxHeap.isEmpty()) System.out.print(maxHeap.poll() + " "); // 50 30 20 10
23        System.out.println();
24
25        // Gerçek senaryo: görev zamanlayıcı — düşük 'oncelik' sayısı = daha acil.
26        PriorityQueue<Gorev> zamanlayici = new PriorityQueue<>(Comparator.comparingInt(Gorev::oncelik));
27        zamanlayici.add(new Gorev("e-posta gönder", 5));
28        zamanlayici.add(new Gorev("sistem çökmesi!", 1));
29        zamanlayici.add(new Gorev("rapor üret", 3));
30        System.out.println("\nGörevler önceliğe göre işleniyor:");
31        while (!zamanlayici.isEmpty()) {
32            Gorev g = zamanlayici.poll();
33            System.out.println("  [" + g.oncelik() + "] " + g.ad());
34        }
35
36        System.out.println("""
37
38                --- PriorityQueue (öncelik kuyruğu) ---
39                Elemanları öncelik sırasına göre verir (FIFO değil!). İçte 'heap' (yığın ağacı) kullanır.
40                add/offer O(log n), peek O(1), poll O(log n). peek/poll HER ZAMAN en öncelikliyi verir.
41                Varsayılan min-heap (en küçük); Comparator ile max-heap veya özel öncelik.
42                Kullanım: görev/iş zamanlama, Dijkstra/A* gibi algoritmalar, 'en yakın K eleman'.
43                NOT: kuyruğu gezmek (iterator) SIRALI değildir; sıra yalnızca poll ile ortaya çıkar.""");
44    }
45}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.