7 - Kuyruk (Queue) Veri Yapısı
2026
Kuyruk, elemanların bir uçtan eklendiği ve diğer uçtan çıkarıldığı doğrusal bir veri yapısıdır.
Gündelik örnekler: Banka sırası, yazıcı kuyruğu, müşteri hizmetleri bekleme hattı.
Geçen hafta bağlı listelerde düğümler arasındaki bağlantıyı bozmadan işlem yapmayı gördük. Bu hafta, o yapıyı yeni bir amaç için kullanıyoruz:
Bağlı listeyi kullanarak bir kuyruk oluşturmak.
Bu bağlantıyı şöyle düşünebiliriz:
frontrearYani bu derste bağlı liste mantığını, kuyruk davranışı üretmek için kullanacağız.
Kuyruk, İlk Giren İlk Çıkar kuralı ile çalışır.
Yukarıdaki görselde 1 önce geldiği için kuyruktan ilk çıkacak eleman da odur. FIFO mantığında önemli olan değerlerin büyüklüğü değil, geliş sırasıdır.
Kuyruk üzerinde en sık kullanılan işlemler şunlardır:
enqueue: Kuyruğun sonuna eleman eklerdequeue: Kuyruğun başından eleman çıkarırpeek: Baştaki elemana çıkarmadan bakarisEmpty: Kuyruk boş mu kontrol ederAyrıca iki temel konum vardır:
front: İlk elemanın bulunduğu uçrear: Son elemanın bulunduğu uçÖğrencilerin en sık karıştırdığı nokta şudur:
Bu derste ağırlıklı olarak bağlı liste ile gerçekleştirme üzerinde duracağız.
Kuyruk düzeyinde kullandığımız uçlar ile bağlı listedeki göstericiler şu şekilde eşleşir:
front = headrear = tailYani:
head, kuyruktaki ilk düğümü gösterirtail, kuyruktaki son düğümü gösterirBaşlangıçta kuyruk boşsa:
head == NULLtail == NULLBu durum, kuyrukta henüz hiç düğüm olmadığını gösterir.
head Hem tail Tutuyoruz?Eğer sadece head tutarsak, sona eleman eklemek için her seferinde listenin sonuna kadar gitmemiz gerekir.
head ve tail birlikte tutulursa sona ekleme işlemi doğrudan yapılabilirBu yüzden kuyruk, bağlı liste ile gerçekleştirilirken çoğu zaman iki uç da tutulur.
enqueue, kuyruğun sonuna eleman ekleme işlemidir.
Bağlı liste ile kuyrukta sona ekleme adımları şöyledir:
sonraki alanını NULL yap.head ve tail aynı düğümü göstersin.tail yeni düğümü göstersin, sonra tail güncellensin.#include <stdio.h>
#include <stdlib.h>
struct Node {
int veri;
struct Node *sonraki;
};
struct Node *head = NULL;
struct Node *tail = NULL;Ders İçi Sadeleştirme
Bu derste mantığı sade göstermek için head ve tail işaretçilerini global tuttuk. Daha sonraki aşamalarda bunları ayrı bir Queue yapısı içinde toplamak da mümkündür.
enqueue Gerçeklemesidequeue, kuyruğun başından eleman çıkarma işlemidir.
Baştan çıkarma sırasında şu sıra izlenir:
head düğümünü geçici bir işaretçide tut.head işaretçisini bir sonraki düğüme kaydır.tail değerini de NULL yap.free ile serbest bırak.dequeue Gerçeklemesiint dequeue() {
struct Node *eskiHead;
int veri;
if (head == NULL) {
printf("Kuyruk bos.\n");
return -1;
}
eskiHead = head;
veri = eskiHead->veri;
head = head->sonraki;
if (head == NULL) {
tail = NULL;
}
free(eskiHead);
return veri;
}Küçük Teknik Not
Bu örnekte boş kuyruk durumunu basit tutmak için -1 döndürüyoruz. Gerçek uygulamalarda hata yönetimi, dönüş değeri ile karışmayacak şekilde farklı tasarlanabilir.
enqueue ve dequeue AkışıBaşlangıçta kuyruk boş olsun.
enqueue(10)enqueue(20)enqueue(30)dequeueAşağıdaki durumda kuyrukta yalnızca bir eleman olsun:
Bu elemana dequeue() uygularsak:
head bir sonraki düğüme gider → NULLtail de NULL yapılırYani işlem sonunda:
Bu güncelleme yapılmazsa yapı bozulur.
Bağlı liste ile ve hem head hem tail tutulan bu yapıda:
enqueue → \(O(1)\)dequeue → \(O(1)\)peek → \(O(1)\)Buradaki hız avantajı, head ve tail işaretçilerinin birlikte tutulmasından gelir.
Kuyruk yapısı şu tür durumlarda doğal olarak karşımıza çıkar:
Buradaki ortak fikir şudur: işler, geliş sırasına göre ele alınır.
Not
Bu derste ayrıntılı olarak yalnızca temel kuyruk yapısını ele alıyoruz. Diğer türler, sonraki konular için kısa bir ön bilgidir.
dequeue sonrasında kuyruk boşaldığında tail değerini güncellememekmalloc sonucunu kontrol etmemekfree etmeyi unutmakvoid foo() {
struct Node *etkin = head;
while (etkin != NULL) {
printf("%d ", etkin->veri);
etkin = etkin->sonraki;
}
printf("\n");
}Sorular:
head üzerinde ilerlemek yerine etkin adında geçici bir işaretçi kullanıyoruz?enqueue işlemi hangi uçta yapılır?
frontrearhead = NULLtail = NULLhead = NULL ve tail = NULLhead = tailhead ve tail birlikte tutulursa hangi işlem genellikle \(O(1)\) olur?
enqueue ve dequeue