Skip to main content

🧱 C Programlama ile Kuyruk (Queue) Veri Yapısı Nasıl Oluşturulur?

Kuyruk (Queue), yazılım geliştirme sürecinde sıklıkla kullanılan temel bir veri yapısıdır.
Bu rehberde, C programlama dilinde Kuyruk (Queue) yapısının nasıl oluşturulacağını, dizi tabanlı ve iki yığın (stack) temelli yöntemleriyle öğreneceksiniz.

Kuyruklar İlk Giren İlk Çıkar (FIFO) prensibiyle çalışır. Bu da, kuyrukta ilk eklenen elemanın ilk çıkarıldığı anlamına gelir — tıpkı bir bilet sırasındaki insanlar gibi 🎟️


🎯 Bu Rehberde Ne Öğreneceksiniz?

  • FIFO mantığını ve kuyruk yapısının nasıl çalıştığını öğreneceksiniz.
  • enqueue() ve dequeue() işlemlerini kod örnekleriyle uygulayacaksınız.
  • Dizi tabanlı ve iki yığın (stack) temelli kuyruk yöntemlerini kıyaslayacaksınız.
  • Kuyrukların işletim sistemlerinden ağ programlamaya kadar birçok kullanım alanını keşfedeceksiniz.
  • Bellek yönetimi ve yaygın hatalardan kaçınma yollarını öğreneceksiniz.

🧠 Kuyruk (Queue) Nedir?

Kuyruk, doğrusal (linear) bir veri yapısıdır.
Veriler arka (Rear) uçtan eklenir ve ön (Front) uçtan çıkarılır.
Bu mantık, "İlk Giren İlk Çıkar (FIFO – First In, First Out)" kuralına dayanır.

🎟️ Gerçek Hayat Örneği:
Bir banka kuyruğunda önce gelen müşteri önce hizmet alır.
Kuyruk veri yapısı da bu davranışı bilgisayar belleğinde taklit eder.


⚙️ Kuyrukta Kullanılan Temel İşlemler

İşlemAçıklamaZaman Karmaşıklığı
enqueue()Kuyruğun sonuna (rear) eleman eklerO(1)
dequeue()Kuyruğun başından (front) eleman çıkarırO(1)
isEmpty()Kuyruk boş mu kontrol ederO(1)
isFull()Kuyruk dolu mu kontrol eder (dizi tabanlı)O(1)
front()İlk elemanı görüntülerO(1)
rear()Son elemanı görüntülerO(1)

🔹 1️⃣ Dizi (Array) Tabanlı Kuyruk Uygulaması

Bu en basit kuyruk yaklaşımıdır.
Kuyruk dizinin başında başlar ve arka kısmında yeni elemanlar eklenir.

📐 Çalışma Mantığı

  1. Front ve Rear başlangıçta -1 olarak ayarlanır.
  2. enqueue: Dizi dolu değilse, Rear artırılır ve eleman eklenir.
  3. dequeue: Kuyruk boş değilse, Front artırılır ve eleman çıkarılır.
  4. Son eleman çıkarıldığında Front ve Rear tekrar -1 yapılır.

🧩 Örnek Kod (Dizi Tabanlı Kuyruk)

#include <stdio.h>
#include <stdlib.h>
#define SIZE 100

int queue[SIZE];
int Front = -1;
int Rear = -1;

void enqueue(int value) {
if (Rear == SIZE - 1) {
printf("Hata: Kuyruk Tasmasi (Overflow)\n");
return;
}
if (Front == -1) Front = 0;
queue[++Rear] = value;
printf("%d kuyruga eklendi.\n", value);
}

void dequeue() {
if (Front == -1 || Front > Rear) {
printf("Hata: Kuyruk Bos (Underflow)\n");
return;
}
printf("%d kuyruktan cikarildi.\n", queue[Front++]);
}

void display() {
if (Front == -1 || Front > Rear) {
printf("Kuyruk bos.\n");
return;
}
printf("Kuyruk: ");
for (int i = Front; i <= Rear; i++)
printf("%d ", queue[i]);
printf("\n");
}

int main() {
enqueue(10);
enqueue(20);
enqueue(30);
display();
dequeue();
display();
return 0;
}

💡 Bu örnek, sabit boyutlu bir diziyle temel FIFO mantığını uygular.


🔹 2️⃣ İki Yığın (Stack) ile Kuyruk Uygulaması

C dilinde yığın (stack) yapısını kullanarak da kuyruk davranışı taklit edilebilir. Bu yöntemde iki yığın (S1 ve S2) kullanılır.

📦 Yöntem 1: Enqueue İşlemi Maliyetli (O(n))

Yeni eleman eklenmeden önce S1’deki tüm elemanlar S2’ye aktarılır.

Yeni eleman S1’e eklenir.

S2’deki elemanlar tekrar S1’e taşınır. 👉 Dequeue işlemi artık O(1) hızında olur.

⚡ Yöntem 2: Dequeue İşlemi Maliyetli (O(n))

Enqueue işlemi sadece S1’e yapılır (O(1)).

Dequeue sırasında, eğer S2 boşsa tüm elemanlar S1’den S2’ye aktarılır.

Böylece FIFO düzeni korunur.

💡 Bu yöntem, yığınların LIFO yapısını tersine çevirerek FIFO davranışı elde eder.

🔹 3️⃣ Bağlı Liste (Linked List) ile Kuyruk Simülasyonu

Dinamik bellek sayesinde kuyruk boyutu sınırsız hale gelir. Aşağıdaki örnek, müşteri sırasını simüle eden bir bağlı liste kuyruğu uygular.

#include <stdio.h>
#include <stdlib.h>

typedef struct Dugum {
int data;
struct Dugum* next;
} Dugum;

void enqueue(Dugum** front, Dugum** rear, int data) {
Dugum* yeni = (Dugum*)malloc(sizeof(Dugum));
yeni->data = data;
yeni->next = NULL;
if (*rear == NULL) *front = *rear = yeni;
else {
(*rear)->next = yeni;
*rear = yeni;
}
}

int dequeue(Dugum** front, Dugum** rear) {
if (*front == NULL) {
printf("Kuyruk bos\n");
return -1;
}
Dugum* temp = *front;
int data = temp->data;
*front = (*front)->next;
if (*front == NULL) *rear = NULL;
free(temp);
return data;
}

int main() {
Dugum* front = NULL;
Dugum* rear = NULL;

enqueue(&front, &rear, 1);
enqueue(&front, &rear, 2);
enqueue(&front, &rear, 3);

printf("Cikarilan: %d\n", dequeue(&front, &rear));
printf("Cikarilan: %d\n", dequeue(&front, &rear));
return 0;
}

💡 Bağlı liste, sabit boyut sınırlaması olmayan kuyruk yapıları için idealdir.


⚙️ Kuyrukların Gerçek Kullanım Alanları

Uygulama AlanıAçıklama
CPU Zamanlamasıİşletim sistemlerinde işlemler sırayla yürütülür.
BFS AlgoritmasıGraf aramalarında düğümler seviye seviye gezilir.
Ağ İletişimiVeri paketleri sırayla gönderilip alınır.
SimülasyonlarBanka ve market gibi gerçek dünya modellerinde sıra yönetimi.
Görev YönetimiGörevler, öncelik sırasına göre işlenir.

🧩 Yaygın Hatalar ve İpuçları

HataSebepÇözüm
Overflow (Taşma)Dolu kuyruğa ekleme yapılmasıisFull() ile kontrol et
Underflow (Eksiklik)Boş kuyruğa çıkarma yapılmasıisEmpty() kontrolü ekle
Bellek Sızıntısıfree() unutulmasıHer dequeue işleminden sonra serbest bırak
Yanlış Pointer GüncellemesiFront ve Rear yanlış atanmasıHer işlem sonunda doğru pointer ataması yap
Sonsuz DöngüNULL kontrolünün eksik olmasıif (Front == NULL) kontrolü ekle

⚖️ Dizi vs. Bağlı Liste Kuyruk Karşılaştırması

ÖzellikDizi (Array) KuyrukBağlı Liste Kuyruk
BoyutSabitDinamik
Bellek KullanımıDaha verimliFazla (pointer maliyeti)
HızCache dostu, daha hızlıBellek dağınıklığı nedeniyle biraz yavaş
Overflow RiskiVarYok
Uygulama KarmaşıklığıBasitOrta

❓ Sıkça Sorulan Sorular (SSS)

1️⃣ C dilinde yerleşik bir Kuyruk yapısı var mı?

Hayır, C dilinde yerleşik bir kuyruk yoktur. Dizi veya bağlı listeyle manuel uygulanır.

2️⃣ En kolay kuyruk yöntemi hangisidir?

Bağlı liste yöntemi en esnek ve kolay olanıdır. Taşma riski yoktur.

3️⃣ Dizi tabanlı kuyruğun dezavantajı nedir?

Sabit boyut ve boş alanların tekrar kullanılamaması. Bu nedenle dairesel kuyruk tercih edilir.

4️⃣ Kuyruk ve Yığın farkı nedir?

Kuyruk: FIFO (İlk Giren İlk Çıkar) Yığın: LIFO (Son Giren İlk Çıkar)

5️⃣ İki yığınla kuyruk neden kullanılır?

Yığınların sadece tek uçtan erişimi olduğu için, FIFO sırasını taklit etmek için iki yığın birlikte kullanılır.


🚀 Sonuç

Bu rehberde C programlama dilinde Kuyruk (Queue) veri yapısının nasıl oluşturulacağını adım adım öğrendin. Artık dizi, bağlı liste veya yığın kullanarak farklı kuyruk yapıları geliştirebilir ve FIFO mantığını projelerinde güvenle uygulayabilirsin.

💬 Şimdi sıra sende! Rabisu Bulut Platformu’nda hemen bir C projesi oluştur, kendi kuyruk yapını test et ve performans farklarını gözlemle. ⚡