YZ Destekli Kodlama Notları

Veri Yapıları · Ünite 2

Dizi, Sözlük, Küme ve Listeler (C#)

10 soruluk deneme testine geç ↓

1. Diziler (array)

Dizi, aynı türden birçok değeri bitişik bellek hücrelerinde tutar. Her elemanın yeri, ilk elemanın adresine bir ofset (kayma) eklenerek hesaplanır; bu yüzden erişim çok hızlıdır.

Tek boyutlu dizi

C#'ta indis 0'dan başlar, son indis «uzunluk − 1»dir. «anadolu» harflerini tutan 7 elemanlı dizide ilk harf [0]'da, son harf [6]'da.

int[] sayilar;                 // tanımlama (bildirim)
sayilar = new int[7];          // 7 eleman, hepsi 0
sayilar[0] = 12;               // değer atama

int[] a = new int[] { 13, 4, 26, -7, 0 };
int[] b = { 13, 4, 26, -7, 0 };  // kısa yazım

int orta = a[2];               // 26

Diziyi gezmenin en kolay yolu foreach: «foreach (string ay in aylar) Console.WriteLine(ay);» her elemanı sırayla yazar.

Çok boyutlu dizi

Tablo gibi satır–sütun. Boyutlar köşeli parantez içinde virgülle ayrılır.

int[,] tablo = new int[3, 6];      // 3 satır, 6 sütun
int[,,] kup = new int[2, 3, 4];    // 3 boyutlu

int[,] m =
{
    { 4, -6, -7 },
    { -11, 4, 0 },
    { -12, -9, 15 },
};
int x = m[2, 2];    // 3. satır, 3. sütun → 15
m[1, 0] = 5;

Pürüzlü dizi (jagged array, dizi dizisi)

Her elemanı başka bir dizi olan tek boyutlu dizi. İç dizilerin uzunlukları farklı olabilir, hatta biri hiç atanmamış (null) kalabilir.

int[][] p = new int[4][];        // 4 eleman, hepsi null
p[0] = new int[] { 13, 0, 19 };
p[1] = new int[] { 7, 21, 5, 2, 71 };
// p[2] null kalır
p[3] = new int[] { 26 };

int s = p[1][2];   // 5
p[1][3] = 20;      // 2 → 20

2. Hash tablosu (Hashtable)

Anahtar (key) → değer (value) eşleşmesi tutar; diğer adı hash map. Amacı: anahtarı verilen değeri O(1) sürede, yani koleksiyon ne kadar büyük olursa olsun neredeyse tek adımda bulmak.

Hash fonksiyonu anahtardan kova numarasını hesaplar; değer o kovadan alınır.

C#'ta hazırı var: System.Collections içindeki Hashtable sınıfı. Her çift bir DictionaryEntry nesnesidir (Key ve Value özellikleri).

Hashtable sayiIsim = new Hashtable();
sayiIsim.Add(1, "Bir");
sayiIsim.Add(2, "İki");
// sayiIsim.Add(2, "İki");  → çalışma zamanı hatası: anahtar zaten var

string deger = (string)sayiIsim[1];   // tür dönüşümü gerekir

foreach (DictionaryEntry e in sayiIsim)
    Console.WriteLine($"{e.Key} - {e.Value}");
ÜyeNe yapar?
CountEleman sayısı
Keys / ValuesAnahtarların / değerlerin listesi
Add, Remove, ClearEkle, sil, hepsini sil
Contains, ContainsKeyBu anahtar var mı?
ContainsValueBu değer var mı?

3. Sözlük (Dictionary) ve sıralanmış sözlük

Hashtable'ın sorunu: anahtar ve değer object türünde tutulur. Her okumada tür dönüşümü, arka planda da kutulama / kutudan çıkarma (boxing / unboxing) gerekir. Dictionary<TKey, TValue> bu sorunu çözer: türleri baştan belirtirsin, dönen değer zaten doğru türdedir.

var sozluk = new Dictionary<string, string>
{
    { "elma", "apple" },
    { "kitap", "book" }
};
string d = sozluk["elma"];   // dönüşüm yok
sozluk["kalem"] = "pen";     // yoksa ekler, varsa günceller

foreach (KeyValuePair<string, string> cift in sozluk)
    Console.WriteLine($"{cift.Key} - {cift.Value}");

Olmayan bir anahtarı istersen KeyNotFoundException fırlatılır. Bundan kaçınmanın üç yolu: try-catch bloğu, önce ContainsKey ile kontrol, ya da TryGetValue kullanmak. Okuma, ekleme ve güncelleme O(1)'e yakındır.

SortedDictionary: anahtarları her zaman sıralı tutar. 1, 4, 5, 3, 2 anahtarlarıyla eklenen isimler foreach'te 1, 2, 3, 4, 5 sırasıyla gelir. Bedeli: okuma, ekleme ve silme O(log n).

DictionarySortedDictionarySortedList
SıraYokAnahtara göre sıralıAnahtara göre sıralı
Okuma≈ O(1)O(log n)O(log n)
Ekleme / silme≈ O(1)O(log n)O(n)
Bellek—SortedList'ten fazlaDaha az

4. Kümeler (HashSet, SortedSet)

Küme: tekrarsız ve sırasız elemanlar topluluğu. Bir elemanın «kümede olup olmadığını» hızla sorarsın. HashSet'i, değeri olmayan, yalnızca anahtar tutan bir sözlük gibi düşünebilirsin.

Yeşil bölge her işlemin sonucunu gösteriyor.
İşlemGösterimSonuç (örnekte)HashSet metodu
BirleşimA ∪ B{1, 2, 3, 4, 5}UnionWith
KesişimA ∩ B{3, 4}IntersectWith
FarkA \ B{1, 2}ExceptWith
Simetrik farkA ∆ B{1, 2, 5}SymmetricExceptWith

Örnek kullanım: indirim kodlarını bir HashSet<int>'te tutmak. Girilen kod Contains ile kontrol edilir; varsa «bu kod kullanıldı», yoksa Add ile eklenir. Aynı kodu iki kez saklamak zaten imkânsız.

SortedSet: tekrarsız ama sıralı küme (HashSet + sıralı liste karışımı). HashSet'in metotlarına ek olarak Min, Max ve belli aralığı veren GetViewBetween var. Büyük/küçük harf duyarsız bir karşılaştırıcı verilirse «Melek» ile «melek» tek eleman sayılır.

5. Listeler (ArrayList, List<T>)

Kaç eleman tutacağını bilmiyorsan dev bir dizi açmak yerine boyutu kendiliğinden büyüyen bir yapı kullan.

ArrayList

ArrayList liste = new ArrayList();
liste.AddRange(new int[] { 4, 3, -1 }); // sona koleksiyon ekle
liste.Add(7);                            // sona tek eleman
liste.AddRange(new object[] { "Rabia", "Elif" });
liste.Insert(5, 7.8);                    // 5. indise yerleştir
// → 4, 3, -1, 7, Rabia, 7.8, Elif

int ucuncu = (int)liste[2];              // dönüşüm gerekir

List<T> (generic liste)

ArrayList'in tür güvenli (strongly typed) sürümü; System.Collections.Generic'te. Türü baştan belirtirsin: List<int>, List<string>, List<Ogrenci>. Metot adları ArrayList'le aynı.

var asallar = new List<int>() { 2, 3, 5, 7 };
asallar.Add(11);
Console.WriteLine(asallar.Count);   // 5

// Üç gezinme yolu, aynı çıktı:
asallar.ForEach(x => Console.Write(x + " "));
foreach (var x in asallar) Console.Write(x + " ");
for (int i = 0; i < asallar.Count; i++) Console.Write(asallar[i] + " ");

Hepsi bir arada

YapıNe zaman?
DiziEleman sayısı belli ve sabit, hızlı indis erişimi lazım.
HashtableAnahtarla hızlı arama; türler karışık (eski, generic olmayan).
DictionaryAnahtarla hızlı arama, türler belli. Çoğu durumda ilk tercih.
SortedDictionaryAnahtarlar hep sıralı lazım.
HashSetTekrarsız elemanlar, «var mı?» sorusu, küme işlemleri.
SortedSetTekrarsız ve sıralı; Min / Max lazım.
List<T>Boyutu değişen, tek türlü liste.
ArrayListBoyutu değişen, karışık türlü liste (eski).

Kendini test et!

Cevabı görmek için soruya dokun.

  1. 1.int[] d = new int[5]; satırından sonra d[4] kaçtır, d[5] ne olur?

    ✓ d[4] = 0 (varsayılan). d[5] yok: indisler 0–4, erişmeye çalışmak hata verir.

  2. 2.int[][] p tanımlı ve p[2] null. p[2][0]'ı okumak neden hata verir?

    ✓ Pürüzlü dizinin 3. elemanına hiç iç dizi atanmamış; null bir dizinin elemanı okunamaz.

  3. 3.Dictionary'de olmayan bir anahtarı istemek hangi hatayı verir, nasıl önlenir?

    ✓ KeyNotFoundException. try-catch, ContainsKey ile kontrol ya da TryGetValue kullanılır.

  4. 4.A = {2, 4, 6, 8}, B = {6, 8, 10}. A ∆ B nedir?

    ✓ {2, 4, 10}: yalnızca bir kümede olanlar.

  5. 5.ArrayList'te 4, 3, 4, 9 var. IndexOf(4) ve LastIndexOf(4) ne döndürür? IndexOf(5)?

    ✓ 0 ve 2. IndexOf(5) bulamadığı için −1.

  6. 6.List<int> neden ArrayList'ten daha hızlıdır?

    ✓ Türü baştan bellidir; elemanları object'e kutulayıp geri çıkarmak (boxing/unboxing) gerekmez.

Deneme testi

Sınavda çıkabilecek türden 10 soru. Bir şık seç; doğru cevap ve açıklaması hemen çıkar.

  1. 1.C#'ta aşağıdaki dizi tanımlamalarından hangisi hatalıdır?

  2. 2.int[][] sayilar = { new int[] { 13, 0, 19 }, new int[] { 7, 21, 5, 2, 71 } }; için sayilar[1][2] kaçtır?

  3. 3.Hash tablosunda anahtardan, değerin bulunduğu kovanın numarasını hesaplayan bileşen hangisidir?

  4. 4.Hashtable ve Dictionary için aşağıdakilerden hangisi doğrudur?

  5. 5.Anahtarları her zaman sıralı tutan, ekleme ve silmesi O(log n) olan yapı hangisidir?

  6. 6.A = {1, 2, 3, 4} ve B = {3, 4, 5} ise A \ B kümesi hangisidir?

  7. 7.İki kümenin en az bir ortak elemanı olup olmadığını kontrol eden HashSet metodu hangisidir?

  8. 8.ArrayList'te aranan değer bulunamazsa IndexOf metodu ne döndürür?

  9. 9.List<T>'nin ArrayList'e göre üstünlüğü aşağıdakilerden hangisidir?

  10. 10.Dictionary'de olmayan bir anahtara erişmeye çalışınca oluşan hatadan kaçınmak için hangileri kullanılabilir? I. try-catch II. ContainsKey III. TryGetValue

Bu not ders kitabının yerine geçmez; konu kendi cümlelerimizle, yapay zekâ desteğiyle özetlendi.