C# programlama dilinde stack ve queue gibi temel algoritmik yapılar, verilerin belirli kurallar çerçevesinde nasıl depolanacağını ve işleneceğini belirler. Bu yapılar, yazılım geliştirme süreçlerinde veri yönetimi açısından kritik öneme sahipler. Stack, LIFO (Last In First Out) mantığıyla çalışırken, queue FIFO (First In First Out) prensibine dayanır. Her iki yapı da algoritmaların daha verimli çalışmasını sağlayan önemli veri yapılarıdır.
Stack (Yığın) Yapısı
Stack, verilerin yalnızca bir uçtan eklendiği ve çıkarıldığı doğrusal bir veri yapısıdır. Bu yapıda, en son eklenen veri ilk önce çıkarılır; yani LIFO (Last In, First Out) prensibi geçerlidir. C# dilinde Stack sınıfı System.Collections.Generic namespace’i altında yer alır ve genellikle metod çağrıları, ifade değerlendirme, geri alma işlemleri gibi durumlarda kullanılır.
Stack’in Temel Özellikleri
- Push: Yığına yeni bir eleman ekler.
- Pop: Yığının en üstündeki elemanı çıkarır ve döndürür.
- Peek (veya Top): Yığının en üstündeki elemanı döndürür ancak onu yığından çıkarmaz.
- IsEmpty: Yığının boş olup olmadığını kontrol eder.
Stack Kullanım Örneği (C#)
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Stack<int> stack = new Stack<int>();
stack.Push(10);
stack.Push(20);
stack.Push(30);
Console.WriteLine("Stack'in en üstündeki eleman: " + stack.Peek()); // 30
Console.WriteLine("Çıkarılan eleman: " + stack.Pop()); // 30
Console.WriteLine("Kalan eleman sayısı: " + stack.Count); // 2
}
}
Queue (Kuyruk) Yapısı
Queue veri yapısı, FIFO (First In, First Out) prensibiyle çalışan doğrusal bir yapıdır. Yani ilk giren eleman ilk çıkar. Bu yapı, genellikle işlem sırası önem arz ettiğinde, örneğin yazıcı kuyruğu, görev planlama, BFS algoritmalarında kullanılır. C#, Queue sınıfını da System.Collections.Generic namespace’i altında sunar.
Queue’in Temel Özellikleri
- Enqueue: Kuyruğun sonuna bir eleman ekler.
- Dequeue: Kuyruğun başındaki elemanı çıkarır ve döndürür.
- Peek (veya Front): Kuyruğun başındaki elemanı döndürür, ancak onu çıkartmaz.
- IsEmpty: Kuyruğun boş olup olmadığını kontrol eder.
Queue Kullanım Örneği (C#)
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Queue<string> queue = new Queue<string>();
queue.Enqueue("Ali");
queue.Enqueue("Veli");
queue.Enqueue("Ayşe");
Console.WriteLine("Kuyruğun başındaki eleman: " + queue.Peek()); // Ali
Console.WriteLine("Çıkarılan eleman: " + queue.Dequeue()); // Ali
Console.WriteLine("Kalan eleman sayısı: " + queue.Count); // 2
}
}
Stack ve Queue Arasındaki Farklar
Stack ve queue yapıları temel farkları bakımından dikkat çeker. Stack, LIFO mantığı ile çalışır ve eleman ekleme/çıkarma işlemleri yalnızca bir uçtan yapılır. Queue ise FIFO mantığı ile çalışır ve elemanlar bir uçtan eklenir, diğer uçtan çıkarılır. Ayrıca, stack genellikle derinlik öncelikli arama (DFS) algoritmalarında, queue ise genişlik öncelikli arama (BFS) algoritmalarında tercih edilir.
Stack ve Queue’in Algoritmik Kullanımları
Stack, parantez eşleştirme, infix-prefix-postfix ifade dönüşümleri, metod çağrı yığınları gibi işlemlerde sıklıkla kullanılır. Örneğin bir ifadede parantezlerin doğru açılıp kapandığını kontrol etmek için stack yapısı idealdir.
Queue ise çoklu işlemci ortamlarında görev sıralama, veri akışı yönetimi, graf veri yapılarında BFS gibi işlemler için tercih edilir. Ayrıca, Windows’ta yazıcı kuyruğu gibi günlük hayattaki birçok örneğinde queue yapısının kullanıldığı görülebilir.
Stack ve Queue’in Performans Karşılaştırması
Her iki yapı da genellikle dizi veya bağlı liste (linked list) kullanılarak uygulanır. Stack ve queue için ekleme ve çıkarma işlemleri genellikle O(1) zaman karmaşıklığına sahiptir. Ancak, kuyrukta dinamik boyut değişiklikleri veya dairesel kuyruk gibi özel implementasyonlar performansı etkileyebilir. Stack genellikle daha basit bir yapıya sahiptir çünkü tek bir uçtan işlem yapılırken, queue iki farklı uç üzerinden işlem yapar.
Stack ve Queue’in Alternatif Uygulamaları
C# dilinde bu yapıların farklı versiyonları da mevcuttur. Örneğin:
- Stack<T> ve Queue<T>: Generic koleksiyonlar olup tip güvenliği sağlar.
- ConcurrentStack<T> ve ConcurrentQueue<T>: Çoklu iş parçacıklı (multithreaded) ortamlarda güvenli şekilde kullanılmak üzere tasarlanmıştır.
Bu yapılar, performans ve güvenlik açısından farklı kullanım senaryolarına yanıt verecek şekilde optimize edilmiştir.
Sonuç
Stack ve queue yapıları, C# gibi nesne yönelimli dillerde veri yönetimi açısından önemli yer tutar. LIFO ve FIFO prensipleriyle çalışan bu yapılar, farklı algoritmik ihtiyaçlara çözüm sunar. Stack, özellikle derinlik temelli işlemlerde; queue ise sıralı işlemler ve akış kontrolünde etkili sonuçlar verir. Doğru veri yapısının seçilmesi, algoritmaların verimliliğini doğrudan etkiler.