Bölüm 12: Kılavuzlu İkili Ağaçlar

C ile Veri Yapıları ve Algoritmalar · Çalışma Soruları
n + 1 NULLKurma kurallarıBaşlık düğümüArdıl ve öncülYığınsız gezinmeMorrisSağa / sola ekleme
Sercan KÜLCÜ

Çoktan Seçmeli · Neden Kılavuz?

Soru 1: Üçlü Ağaçta Boş İşaretçi

Her düğümünde üç çocuk işaretçisi bulunan n düğümlü bir ağaçta (n ≥ 1) kaç işaretçi NULL'dır?

A: Toplam 3n işaretçi vardır. Kök dışındaki her düğümü ebeveyninden tam bir işaretçi gösterir: n − 1 dolu. Kalan 3n − (n − 1) = 2n + 1. İkili ağaçta aynı hesap 2n − (n − 1) = n + 1 verir.

Klasik Soru · Neden Kılavuz?

Soru 2: Çağrı Yığını mı, Kılavuz mu?

1.000.000 düğümlü, sola çarpık (her düğümün yalnız sol çocuğu olan) bir ikili ağaç kök ortada geziniliyor. Özyinelemeli gezinmede her çağrı çerçevesi 48 bayt tutuyor. Yığın en çok kaç çerçeveye ve yaklaşık ne kadar belleğe ulaşır? Kılavuzlu ağaçtaki gezinme ne kadar ek bellek ister?

Cevabı göster
  • Kökten en soldaki yaprağa kadar 1.000.000 çağrı iç içe açılır, yaprağın NULL sol çocuğuyla bir çağrı daha: 1.000.001 çerçeve, yaklaşık 1.000.001 × 48 ≈ 48 MB.
  • Varsayılan yığın tipik olarak 1–8 MB'dır: program yığın taşmasıyla çöker.
  • Kendi yığınını tutan döngüsel gezinme de O(h) = 1.000.000 işaretçi (≈ 8 MB, heap'te) ister.
  • Kılavuzlu gezinme yalnızca p işaretçisini kullanır: ek bellek O(1); bedeli düğüm başına iki bayraktır.

Klasik Soru · Kurma Kuralları

Soru 3: Kılavuzları Belirlemek

Kök ortada sırası N L Q O K M P olan ağaç şekildedir (kesikli bağlar henüz yok). Kılavuzlu hâle getirilince hangi işaretçi hangi düğümü gösterir? Kaç kılavuz başlığa gider?

NLQOKMP
Cevabı göster
düğümsol kılavuz → öncülsağ kılavuz → ardıl
NbaşlıkL
QLO
O(gerçek çocuk Q)K
MK(gerçek çocuk P)
PMbaşlık
başbaşbaşNLQOKMP

7 düğüm → 8 = n + 1 kılavuz; 2'si (N'nin solu, P'nin sağı) başlığa gider.

Çoktan Seçmeli · Kurma Kuralları

Soru 4: Başlığı Gösteren Sol Kılavuz

Kılavuzlu bir ağaçta bir düğümün solKilavuz alanı TRUE ve solCocuk alanı başlık düğümünü gösteriyor. Bu düğüm için hangisi kesinlikle doğrudur?

B: Sol kılavuz kök ortada öncülü gösterir; öncül yerine başlık varsa düğümün öncülü yoktur, yani ilk ziyaret edilendir. Bu düğümün sağ alt ağacı olabilir, yani yaprak olmak zorunda değildir; sol alt ağacı olmayan kök de bu düğüm olabilir ama her zaman kök değildir.

Çoktan Seçmeli · Kurma Kuralları

Soru 5: Yalnızca Sağ Kılavuzlar

Bir ağaçta yalnızca sağ NULL işaretçiler kök ortada ardıla çevrilmiş, sol NULL'lar NULL bırakılmıştır (sağ bayraklar tutuluyor). Bu ağaçta O(1) ek bellekle hangisi yapılabilir?

C: kokortada_ardil_bul yalnızca sağ işaretçiyi, sağ bayrağı ve sol çocuk bağlarını kullanır (en sola inerken sol NULL, döngüyü durdurur). Öncül ve ters gezinme sol kılavuzlara gerek duyar; kök sonda ise ebeveyn bilgisi ister.

Hata Bulma · Kurma Kuralları

Soru 6: Bayraksız En Sol

Kılavuzlu ağaçta kök ortada ilk düğümü bulmak için aşağıdaki yordam yazılmıştır. Üçüncü sorudaki ağaçta ne olur? Yordamı düzeltin.

kilavuz_gost en_sol(kilavuz_gost bas) {
  kilavuz_gost p = bas->solCocuk;  /* kök */
  while (p->solCocuk != NULL)
    p = p->solCocuk;
  return p;
}
Cevabı göster

Kılavuzlu ağaçta hiçbir solCocuk NULL değildir: N'nin solu başlığı, başlığın solu yeniden kökü gösterir. p sırasıyla K, L, N, başlık, K, L, N … olur: sonsuz döngü.

Düzeltilmiş gövde:

kilavuz_gost p;
if (bas->solKilavuz)
  return NULL;          /* boş ağaç */
p = bas->solCocuk;
while (!p->solKilavuz) /* gerçek */
  p = p->solCocuk;
return p;

Boş ağaçta başlığın solKilavuz'u TRUE'dur; bu durum ayrıca ele alınır. Aynı işi kokortada_ardil_bul(bas) da yapar (boş ağaçta başlığı döndürür).

Çoktan Seçmeli · Kök Ortada Gezinme

Soru 7: Kökün Öncülü

Üçüncü sorudaki kılavuzlu ağaçta kokortada_oncel_bul(K) hangi düğümü döndürür?

kilavuz_gost kokortada_oncel_bul(kilavuz_gost L) {
  kilavuz_gost p = L->solCocuk;
  if (!L->solKilavuz)
    while (!p->sagKilavuz) p = p->sagCocuk;
  return p;
}

D: K'nin sol işaretçisi gerçek çocuktur (L); sol alt ağacın en sağına inilir: L'nin sağı gerçek (O), O'nun sağı kılavuzdur (sagKilavuz TRUE) → O. Kök ortada sırada da K'den hemen önce O gelir: N L Q O K. Q, O'nun sol alt ağacında olduğu için ondan öncedir.

Adım Adım Çalıştırma · Kök Ortada Gezinme

Soru 8: Yığınsız Kök Ortada Gezinme

Üçüncü sorudaki ağaçta kilavuz_kokortada_dolas(bas) çalışıyor. Her turda p nereye gider, kaç işaretçi izlenir (p'ye yapılan her atama bir sayılır)?

başbaşbaşNLQOKMP

p başlıkta başlar. Yığın ya da özyineleme yok; tek işaretçi yeter.

başbaşbaşNLQOKMP

Başlığın sağı kendisi, bayrağı FALSE → sola in: K, L, N; N'nin solu kılavuz → N (4 işaretçi).

başbaşbaşNLQOKMP

N'nin sağı kılavuz: ardıl doğrudan L.

başbaşbaşNLQOKMP

L'nin sağı gerçek (O); O'nun solu gerçek → Q; Q'nun solu kılavuz → Q.

başbaşbaşNLQOKMP

Q'nun sağ kılavuzu → O.

başbaşbaşNLQOKMP

O'nun sağ kılavuzu → K.

başbaşbaşNLQOKMP

K'nin sağı gerçek (M); M'nin solu kılavuz, döngü hiç dönmez → M.

başbaşbaşNLQOKMP

M'nin sağı gerçek (P); P'nin solu kılavuz → P.

başbaşbaşNLQOKMP

P'nin sağ kılavuzu başlığı gösterir → döngü biter. 12 işaretçi izlendi: n + 1 = 8 çağrı, 4 gerçek sol bağ. O(n), ek bellek O(1).

kilavuz_gost kokortada_ardil_bul(kilavuz_gost L) {
  kilavuz_gost p = L->sagCocuk;
  if (!L->sagKilavuz)
    while (!p->solKilavuz)
      p = p->solCocuk;
  return p;
}
void kilavuz_kokortada_dolas(kilavuz_gost L) {
  kilavuz_gost p = L;
  for (;;) {
    p = kokortada_ardil_bul(p);
    if (p == L) break;
    printf("%c ", p->veri);
  }
}

Çıktı Sorusu · Kök Ortada Gezinme

Soru 9: Kök Önde Kılavuzlu Gezinme

Üçüncü sorudaki ağaçta başlıktan başlanıp kokonde_ardil_bul başlığa dönene kadar çağrılıyor ve her düğüm yazdırılıyor. Çıktı nedir? kokonde_ardil_bul(Q) hangi düğümü döndürür ve bu sırada kaç sağ kılavuz izlenir?

kilavuz_gost kokonde_ardil_bul(kilavuz_gost p) {
  if (!p->solKilavuz)   /* sol çocuk varsa o */
    return p->solCocuk;
  while (p->sagKilavuz)  /* kılavuzlarla çık */
    p = p->sagCocuk;
  return p->sagCocuk;    /* ilk gerçek sağ */
}
Cevabı göster

Çıktı: K L N O Q M P (kök önde sıra).

  • Q'nun sol çocuğu yok (sol kılavuz TRUE); sağ kılavuzlarla çıkılır: Q → O (1), O'nun sağı da kılavuz → K (2).
  • K'nin sağ işaretçisi gerçek çocuktur: döngü durur ve K->sagCocuk = M döner. 2 kılavuz izlendi.
  • Q, O'nun sol alt ağacının son düğümüdür; O'nun sağı boş olduğu için sıra K'nin sağ alt ağacına geçer.

Çoktan Seçmeli · Kök Ortada Gezinme

Soru 10: Morris Gezinmesinin Bedeli

Morris gezinmesi için hangisi doğrudur?

A: Kılavuz, öncülün boş sağ işaretçisine geçici olarak yazılır ve o düğüme ikinci kez gelindiğinde sökülür. Bu yüzden bayrak gerekmez ve gezinme bitince ağaç eski hâlini alır. Gezinme sırasında ağaç değiştiği için aynı anda başka bir okuyucu yanlış bağ görebilir.

Adım Adım Çalıştırma · Kök Ortada Gezinme

Soru 11: Morris Gezinmesi Adım Adım

Aynı ağaç, bu kez kılavuzsuz ve bayraksız tutuluyor. morris_kokortada(kok) hangi geçici kılavuzları kurup söker, ne yazdırır?

NLQOKMP

Başlangıç: sıradan ağaç, bayrak yok.

NLQOKMP

K'nin öncülü O (L'den sağa sağa). O'nun sağı boş → geçici kılavuz O → K, sola in.

NLQOKMP

L'nin öncülü N; kılavuz N → L kurulur, sola in.

NLQOKMP

N'nin solu yok: yaz, sağa geç; sağ işaretçi geçici kılavuz olduğu için L'ye döner.

NLQOKMP

Öncül N'nin sağı zaten L: kılavuz sökülür, L yazılır, sağa (O).

NLQOKMP

O'nun öncülü Q; kılavuz Q → O kurulur, sola in.

NLQOKMP

Q yazılır; geçici kılavuzla O'ya dönülür.

NLQOKMP

Q → O sökülür, O yazılır; O'nun sağı (geçici kılavuz) K'ye götürür.

NLQOKMP

K'nin öncülü O'nun sağı K: kılavuz sökülür, K yazılır, sağa (M).

NLQOKMP

M'nin solu yok: yaz, sağa (P).

NLQOKMP

P yazılır, L = NULL: bitti. 10 tur, 3 geçici kılavuz (solu olan her düğüm için bir); ağaç eski hâlinde.

void morris_kokortada(agac_gost L) {
  while (L) {
    if (!L->solcocuk) {
      printf("%c", L->veri);  L = L->sagcocuk;
    } else {
      agac_gost p = L->solcocuk;
      while (p->sagcocuk && p->sagcocuk != L)
        p = p->sagcocuk;
      if (!p->sagcocuk) {
        p->sagcocuk = L;  L = L->solcocuk;
      } else {
        p->sagcocuk = NULL;
        printf("%c", L->veri);  L = L->sagcocuk;
      }
    }
  }
}

Kod Yazma · Düğüm Ekleme

Soru 12: Kılavuzlu Arama Ağacında Arama

Kılavuzlu bir ikili arama ağacında (başlık düğümlü, char veri) x değerini arayan kilavuz_gost kilavuz_ara(kilavuz_gost bas, char x) yordamını yazın. Bulunamazsa NULL dönsün; boş ağaç da doğru ele alınsın. Arama, kılavuzlu ağaca ekleme yordamının da ilk adımıdır.

Cevabı göster
kilavuz_gost kilavuz_ara(kilavuz_gost bas, char x) {
  kilavuz_gost p = bas->solCocuk;
  short kil = bas->solKilavuz;    /* boş: TRUE */
  while (!kil) {                  /* gerçek düğüm */
    if (x == p->veri) return p;
    if (x < p->veri) {
      kil = p->solKilavuz;  p = p->solCocuk;
    } else {
      kil = p->sagKilavuz;  p = p->sagCocuk;
    }
  }
  return NULL;     /* kılavuza çarptı: yok */
}

Sıradan BST'de NULL'a gelince durulurdu; burada izlenen işaretçinin bayrağı TRUE ise (kılavuz) x ağaçta yoktur. Ekleme için tam bu noktada x küçükse sola_ekle, büyükse saga_ekle çağrılır. O(h).

Adım Adım Çalıştırma · Düğüm Ekleme

Soru 13: saga_ekle(L, X): İkinci Durum

Üçüncü sorudaki ağaca saga_ekle(L, X) uygulanıyor. L'nin sağ alt ağacı (O) olduğu için ikinci durumdur. Hangi alanlar değişir, yeni kök ortada sıra nedir?

başbaşbaşNLQOKMP

Önce: L'nin sağı gerçek çocuk O. X yeni düğüm, alanları henüz boş.

X'in sağına L'nin eski sağ alt ağacı (O) gelir; bayrak da kopyalanır: FALSE, gerçek bağ.

X'in kök ortada öncülü L: sol işaretçi L'ye, sol bayrak TRUE (kılavuz).

L → X gerçek bağı kurulur. L'nin bayrağı zaten FALSE idi; birinci durum için bu satır gereklidir.

X'in sağ bayrağı FALSE → X'in ardılı aranır: O'dan en sola, Q. Q'nun sol kılavuzu hâlâ L'yi gösteriyor.

başbaşbaşNLXQOKMP

Q'nun öncülü artık X. Yeni sıra: N L X Q O K M P. 7 atama; ardıl araması yüzünden O(h).

void saga_ekle(kilavuz_gost baba,
               kilavuz_gost cocuk) {
  kilavuz_gost p;
  cocuk->sagCocuk   = baba->sagCocuk;
  cocuk->sagKilavuz = baba->sagKilavuz;
  cocuk->solCocuk   = baba;
  cocuk->solKilavuz = TRUE;
  baba->sagCocuk    = cocuk;
  baba->sagKilavuz  = FALSE;
  if (!cocuk->sagKilavuz) {
    p = kokortada_ardil_bul(cocuk);
    p->solCocuk = cocuk;
  }
}

Çoktan Seçmeli · Düğüm Ekleme

Soru 14: Sabit TRUE Bayrak

saga_ekle'de cocuk->sagKilavuz = baba->sagKilavuz; satırı cocuk->sagKilavuz = TRUE; yapılıyor. Aynı saga_ekle(L, X) çağrısından sonra kök ortada gezinme ne yazdırır?

C: X'in sağ işaretçisi O'yu gösterir ama TRUE bayrağı yüzünden kılavuz sanılır; ardıl(X) doğrudan O olur ve O'nun sol alt ağacındaki Q atlanır. Bayrak TRUE olduğu için if bloğu da çalışmaz; Q'nun sol kılavuzu L'de kalır. Döngü yoktur, gezinme başlığa ulaşıp biter.

Çoktan Seçmeli · Düğüm Ekleme

Soru 15: saga_ekle Neleri Değiştirir?

saga_ekle(baba, cocuk) çağrısında cocuk dışında hangi düğümlerin alanları değişebilir?

D: baba'da yalnız sagCocuk ve sagKilavuz yazılır. İkinci durumda cocuk'un yeni ardılı (baba'nın eski ardılı) eskiden öncül olarak baba'yı gösteriyordu; onun solCocuk'u cocuk yapılır. Başka hiçbir kılavuz cocuk'un hemen öncesini ya da sonrasını göstermediği için değişmez.

Klasik Soru · Düğüm Ekleme

Soru 16: sola_ekle: Birinci Durum

Üçüncü sorudaki ağaca sunumdaki sola_ekle(M, Y) uygulanıyor. M'nin sol alt ağacı yoktur. Y'nin dört alanı ve M'nin sol alanları ne olur? if bloğu çalışır mı? Yeni kök ortada sıra nedir?

void sola_ekle(kilavuz_gost baba,
               kilavuz_gost cocuk) {
  cocuk->solCocuk   = baba->solCocuk;
  cocuk->solKilavuz = baba->solKilavuz;
  cocuk->sagCocuk   = baba;
  cocuk->sagKilavuz = TRUE;
  baba->solCocuk    = cocuk;
  baba->solKilavuz  = FALSE;
  if (!cocuk->solKilavuz) {
    kilavuz_gost p = kokortada_oncel_bul(cocuk);
    p->sagCocuk = cocuk;
  }
}
Cevabı göster
  • Y->solCocuk = M->solCocuk = K, Y->solKilavuz = TRUE (M'nin eski öncül kılavuzu Y'ye geçer).
  • Y->sagCocuk = M, Y->sagKilavuz = TRUE: Y'nin ardılı M.
  • M->solCocuk = Y, M->solKilavuz = FALSE: gerçek bağ.
  • Y'nin sol bayrağı TRUE olduğu için if bloğu çalışmaz: Y'den önce gelen K'nin sağı gerçek çocuk (M) olduğundan düzeltilecek kılavuz yoktur.

Yeni sıra: N L Q O K Y M P.

Son

Bölüm 12: Kılavuzlu İkili Ağaçlar — Çalışma Soruları
Konu anlatımı: Kılavuzlu ikili ağaçlar sunumu · Ders notu · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.