Queue (Kuyruk)
Son güncelleme
Bir queue (kuyruk) iki ucundan da canlıdır. Yeni değerler sondan katılır, değerler baştan ayrılır; böylece en uzun bekleyen ilk hizmeti alır. FIFO budur ve bir gişedeki sıranın davranışı da tam olarak böyledir: arkadan katılıp önden hizmet almak, beklemeyi adil kılan şeydir. Yukarıdan Oynat'a basın; değerlerin bir taraftan girip diğer taraftan çıkmasını izleyin.
Her uç kendi indeksi veya işaretçisiyle izlendiği için iki işlem de O(1)'dir ve hiçbiri verinin geri kalanını kaydırmaz. İşi geliş sırasına göre işleyen her şeyin altında bu yüzden bir kuyruk vardır: yazdırma işleri, görev ve mesaj kuyrukları, istek tamponları ve grafı seviye seviye gezen genişlik öncelikli arama, ki bunu tam olarak sınırını bir kuyrukta tuttuğu için yapar. Çıkarmanın yapıldığı ucu arkaya taşıyın, elinizde bunun yerine bir stack olur.
Zaman ve alan karmaşıklığı
İki standart uygulama olan dairesel tampon (ring buffer) veya bağlı liste tabanlı bir kuyruk için:
| İşlem | Karmaşıklık | Notlar |
|---|---|---|
| Enqueue (sona ekleme) | O(1) | Değeri sona yazar ve son indeksini ilerletir. |
| Dequeue (baştan çıkarma) | O(1) | Baştaki değeri okur ve baş indeksini ilerletir, hiçbir kaydırma olmadan. |
| Peek (başa bakma) | O(1) | Baştaki değeri çıkarmadan okur. |
| Arama | O(n) | Kuyruk bunun için değildir: içine bakmak için onu boşaltmanız gerekir. |
| Alan | O(n) | Bekleyen her değer için bir yuva. |
Adım adım
| Adım | Ne olur |
|---|---|
| 1 | Kuyruk boş başlar; baş ve son aynı yuvayı gösterir. |
| 2 | Enqueue değeri sona yazar, ardından sonu bir ilerletir. |
| 3 | Sonraki her enqueue, zaten bekleyen değerlerin arkasına oturur. |
| 4 | Dequeue baştaki değeri okur, ardından başı bir ilerletir. |
| 5 | Geri dönen değer daima en uzun bekleyen değerdir. |
| 6 | Baş ile son buluştuğunda kuyruk yeniden boşalmıştır ve bir çıkarma daha yapmak hatadır. |
Çözümlü örnek
3, 7, 5 değerlerini ekleyip ardından kuyruğu boşaltma:
| İşlem | Kuyruk (baştan sona) | Döndürdüğü |
|---|---|---|
enqueue(3) | [3] | hiçbir şey |
enqueue(7) | [3, 7] | hiçbir şey |
enqueue(5) | [3, 7, 5] | hiçbir şey |
dequeue() | [7, 5] | 3, en eski değer |
dequeue() | [5] | 7 |
dequeue() | [] | 5, en yeni değer, en sonda |
Queue ne zaman kullanılır
| Şu durumlarda kullanın | Şu durumlarda kaçının |
|---|---|
| İşler geliş sırasına göre ele alınmalıysa: iş kuyrukları, istek tamponları, yazdırma spoolerları | En son eklenen öğeye önce ihtiyacınız varsa; bunun için bir stack vardır |
| Genişlik öncelikli aramanın yaptığı gibi seviye seviye keşfediyorsanız | Öğeler geliş sırasına göre değil önceliğe göre işlenmeliyse; burada bir heap uygundur |
| Bir üretici ile bir tüketici farklı hızlarda çalışıyor ve aralarında bir tampona ihtiyaç duyuyorsa | Verinin ortasında arama yapmanız veya indeksle erişmeniz gerekiyorsa |
Elemanları kaydırmadan O(1) ekleme ve çıkarma istiyorsanız | Onu her dequeue işleminde diziyi kaydırarak gerçekleyecekseniz; bu onu O(n) yapar |
Queue kodu
Python, JavaScript, Java, C++, C dillerinde temiz ve çalıştırılabilir bir Queue uygulaması. Bir dil seçin, kodu kopyalayın veya Coddy Playground'da hazır yüklenmiş olarak açın.
Python ile Queue kodu
1from collections import deque2
3queue = deque()4
5# Enqueue three values at the rear6for value in [3, 7, 5]:7 queue.append(value)8 print(f"enqueue {value} -> {list(queue)}")9
10# Dequeue them from the front: first in, first out11while queue:12 value = queue.popleft()13 print(f"dequeue {value} -> {list(queue)}")14
15print("empty:", len(queue) == 0)JavaScript ile Queue kodu
1// A plain array makes dequeue O(n): shift() moves every element left.2// Track a head index instead, the fix the queue article describes.3const queue = { items: [], head: 0 };4
5function enqueue(value) {6 queue.items.push(value);7}8
9function dequeue() {10 const value = queue.items[queue.head];11 queue.items[queue.head] = undefined; // free the slot12 queue.head += 1;13 // Reclaim space once the consumed prefix dominates.14 if (queue.head * 2 >= queue.items.length) {15 queue.items = queue.items.slice(queue.head);16 queue.head = 0;17 }18 return value;19}20
21const size = () => queue.items.length - queue.head;22
23for (const value of [3, 7, 5]) {24 enqueue(value);25 console.log(`enqueue ${value} -> size ${size()}`);26}27
28// Dequeue from the front: first in, first out, amortized O(1)29while (size() > 0) {30 console.log(`dequeue ${dequeue()} -> size ${size()}`);31}32
33console.log('empty:', size() === 0);Java ile Queue kodu
1import java.util.ArrayDeque;2import java.util.Queue;3
4public class Main {5 public static void main(String[] args) {6 Queue<Integer> queue = new ArrayDeque<>();7
8 // Enqueue three values at the rear9 for (int value : new int[] {3, 7, 5}) {10 queue.add(value);11 System.out.println("enqueue " + value + " -> " + queue);12 }13
14 // Dequeue them from the front: first in, first out15 while (!queue.isEmpty()) {16 int value = queue.remove();17 System.out.println("dequeue " + value + " -> " + queue);18 }19
20 System.out.println("empty: " + queue.isEmpty());21 }22}C++ ile Queue kodu
1#include <iostream>2#include <queue>3
4int main() {5 std::queue<int> queue;6
7 // Enqueue three values at the rear8 for (int value : {3, 7, 5}) {9 queue.push(value);10 std::cout << "enqueue " << value << " -> size " << queue.size() << "\n";11 }12
13 // Dequeue them from the front: first in, first out14 while (!queue.empty()) {15 int value = queue.front();16 queue.pop();17 std::cout << "dequeue " << value << " -> size " << queue.size() << "\n";18 }19
20 std::cout << "empty: " << std::boolalpha << queue.empty() << "\n";21 return 0;22}C ile Queue kodu
1#include <stdio.h>2
3#define CAP 164
5int queue[CAP];6int front = 0;7int rear = 0; /* index of the next free slot */8
9int main(void) {10 int values[3] = {3, 7, 5};11
12 /* Enqueue three values at the rear */13 for (int i = 0; i < 3; i++) {14 queue[rear++] = values[i];15 printf("enqueue %d -> size %d\n", values[i], rear - front);16 }17
18 /* Dequeue them from the front: first in, first out */19 while (front < rear) {20 int value = queue[front++];21 printf("dequeue %d -> size %d\n", value, rear - front);22 }23
24 printf("empty: %d\n", front == rear);25 return 0;26}Queue SSS
FIFO ne demek?
Queue ile stack arasındaki fark nedir?
O(1) ile ekler; queue baştan çıkarır (FIFO), stack ise eklediği uçtan çıkarır (LIFO). Bunun dışında karmaşıklık tabloları aynıdır.Kuyruğun temel işlemleri nelerdir?
enqueue sona bir değer ekler, dequeue baştaki değeri çıkarıp döndürür, peek (veya front) baştaki değeri çıkarmadan okur ve is_empty bekleyen bir şey olup olmadığını bildirir. Dördü de O(1)'dir.Düz bir dizi kullanırsam dequeue neden yavaş olur?
O(n) yapar. Gerçek uygulamalar bunu, baş indeksini ilerleten bir dairesel tamponla ya da baş işaretçisi olan bir bağlı listeyle önler. Python'daki collections.deque ve Java'daki ArrayDeque bunu sizin için yapar, list.pop(0) ise yapmaz.Dairesel kuyruk nedir?
n kapasiteli bir kuyruk, dizinin sonundan taşmak yerine süresiz olarak çalışmayı sürdürür.