Bölüm 10: Ağaçlar

Bölüm 10: Ağaçlar · Çalışma Soruları
Terminolojiİkili ağaçGösterimGezinmelerİteratif gezinmeDüzey sırası ve yordamlar
Sercan KÜLCÜ

Çoktan Seçmeli · Terminoloji

Soru 1: Derece, Derinlik, Ata

Şekildeki ağaçta (kök 1. düzeyde) ağacın derecesi, derinliği ve K'nın ataları hangisidir?ABCDEFGHIJKL

A: Derece en çok çocuklu düğümün çocuk sayısıdır: A ve D üçer → 3. Derinlik en büyük düzeydir: J, K, L 4. düzeyde. Atalar kökten K'ya giden yoldaki düğümlerdir: A, D, H. C seçeneği CLRS'teki yüksekliği (kenar sayısı: 3) verir.

Çoktan Seçmeli · İkili Ağaç

Soru 2: Lemmadan Sayılar

Derinliği 6 olan bir ikili ağaçta (kök 1. düzey) en çok kaç düğüm, 6. düzeyde en çok kaç düğüm ve toplamda en az kaç düğüm bulunur?

C: k derinlikte en çok 2ᵏ − 1 = 63 düğüm; i. düzeyde en çok 2ⁱ⁻¹ = 32. Derinliğin 6 olması için her düzeyde en az bir düğüm gerekir: en az 6 (çarpık ağaç). D, 7 derinliğin değerlerini verir.

Çoktan Seçmeli · İkili Ağaç

Soru 3: Yapraklar ve NULL Bağlar

Bir ikili ağaçta 12 yaprak ve 5 tek çocuklu düğüm vardır. Toplam düğüm sayısı ve bağlı gösterimdeki NULL işaretçi sayısı nedir?

D: n₀ = n₂ + 1 → n₂ = 11. n = 12 + 5 + 11 = 28. 2n = 56 işaretçiden n − 1 = 27'si dolu (kök dışında her düğüme bir bağ girer); NULL olan 56 − 27 = n + 1 = 29.

Klasik Soru · Gösterim

Soru 4: Diziden Ağaca

1 tabanlı dizi gösteriminde agac[1..9] = A B C D – E F – G (– boş göz). Ağacı çizin. G'nin ebeveyni kimdir, G sol mu sağ çocuk mu? Derinlik kaçtır ve bu derinlikte genel bir ikili ağaç için kaç göz açılmalıdır?

Cevabı göster ABCDEFG
  • Çocuklar 2i ve 2i + 1'dedir: A(1) → B(2), C(3); B(2) → D(4), 5 boş; C(3) → E(6), F(7); D(4) → 8 boş, G(9).
  • G: baba(9) = ⌊9/2⌋ = 4 → D; 9 tek olduğu için sağ çocuk.
  • Derinlik 4 → 2⁴ − 1 = 15 göz. 7 düğüm için 15 göz: ağaç tam olmadığı için yer boşa gider.

Çoktan Seçmeli · Gösterim

Soru 5: 0 Tabanlı Dizide Formüller

Kök agac[0]'a konur ama formüller değiştirilmeden solcocuk(i) = 2i, sagcocuk(i) = 2i + 1 kullanılırsa ne olur?

C: solcocuk(0) = 0: kök kendinin çocuğu olur, gezinme sonsuza gider; sagcocuk(0) = 1 de sol çocuğun yerine düşer. 0 tabanlıda sol 2i + 1, sağ 2i + 2, ebeveyn ⌊(i − 1)/2⌋'dir.

Klasik Soru · Gösterim

Soru 6: Ağacı Silmenin Sırası

Aşağıdaki agac_sil neden hatalıdır? İki farklı düzeltme yazın.

void agac_sil(agac_gost L) {
  if (!L) return;
  free(L);
  agac_sil(L->solcocuk);
  agac_sil(L->sagcocuk);
}
Cevabı göster

Kök önce free edildikten sonra L->solcocuk ve L->sagcocuk okunuyor: serbest bırakılmış bellek okunur (sarkan işaretçi, tanımsız davranış). Testte bazen çalışıyor görünmesi hatayı gizler.

/* 1) kök sonda */
void agac_sil(agac_gost L) {
  if (!L) return;
  agac_sil(L->solcocuk);
  agac_sil(L->sagcocuk);
  free(L);
}
/* 2) bağları önce sakla */
void agac_sil2(agac_gost L) {
  if (!L) return;
  agac_gost s = L->solcocuk, g = L->sagcocuk;
  free(L);
  agac_sil2(s); agac_sil2(g);
}

Birinci sürüm kök sonda gezinmedir; ikincisi çocukları önce saklar. İkisinde de n düğüm için n free (sayaçla doğrulandı).

Çoktan Seçmeli · Gösterim

Soru 7: Sol Çocuk – Sağ Kardeş

Genel ağaç A(B(E, F), C, D(G)) sol çocuk – sağ kardeş yöntemiyle ikili ağaca çevriliyor. Elde edilen ikili ağacın kök ortada sırası nedir?

D: A.sol = B; B.sol = E, B.sağ = C; E.sağ = F; C.sağ = D; D.sol = G. Kök ortada: E F B C G D A (programla doğrulandı). Bu, genel ağacın kök sonda sırasıdır. A seçeneği kök önde sırasıdır; o iki ağaçta aynıdır.

Klasik Soru · Gezinmeler

Soru 8: İfade Ağacı

(a - b) * c + d / (e + f) ifadesinin ağacını çizin; kök önde, kök ortada ve kök sonda sıralarını yazın. a = 9, b = 3, c = 2, d = 8, e = 1, f = 3 için kök sonda sırasını yığınla hesaplayın.

Cevabı göster +*/-cd+ abef
  • Kök önde: + * - a b c / d + e f
  • Kök ortada (parantezle): ((a - b) * c) + (d / (e + f))
  • Kök sonda: a b - c * d e f + / +

Hesap: 9 − 3 = 6, 6 · 2 = 12, 1 + 3 = 4, 8 / 4 = 2, 12 + 2 = 14 (eval ile doğrulandı). Kök en son işlenir: önce iki alt ifadenin değeri gerekir.

Adım Adım Çalıştırma · Gezinmeler

Soru 9: Derinliği Hesaplamak

derinlik yordamı A(B(–, D(E, –)), C) ağacı için çağrılıyor. Her düğüm ne döndürür, sonuç kaçtır?

ABCDE

A'nın sol çocuğu B için çağrı; A'nın çerçevesi bekler.

ABCDE

B'nin solu NULL → 0 döndü (s = 0). Şimdi sağ çocuk D.

ABCDE

D'nin sol çocuğu E için çağrı: yığın en derin hâlinde, 5 çerçeve.

ABCDE→1

E yaprak: iki çocuk 0 → 1 + 0 = 1 döner.

ABCD→2E→1

D: s = 1, g = 0 (NULL) → 2.

AB→3CD→2E→1

B: s = 0, g = 2 → 3.

AB→3C→1D→2E→1

A'ya dönüldü, s = 3. Sağ çocuk C yapraktır → 1.

A→4B→3C→1D→2E→1

A: 1 + max(3, 1) = 4. Kök sonda düzeni: önce iki alt ağaç, sonra düğüm. O(n) zaman, O(h) yığın.

int derinlik(agac_gost L) {
  if (!L) return 0;
  int s = derinlik(L->solcocuk);
  int g = derinlik(L->sagcocuk);
  return 1 + (s > g ? s : g);
}

Çoktan Seçmeli · Gezinmeler

Soru 10: NULL Çağrıları

12 düğümlü bir ikili ağaç özyinelemeli kok_onde_dolas ile geziliyor (çağrıdan önce NULL denetimi yok). Toplam kaç çağrı yapılır, bunların kaçı NULL ile yapılır?

B: Her düğüm için bir çağrı (12) ve her NULL bağ için bir çağrı yapılır; NULL bağ sayısı n + 1 = 13. Toplam 2n + 1 = 25; çağrı ağacı, yaprakları NULL çağrıları olan ağacın kendisidir (15 düğümlü ağaçta 31 ve 16 ölçüldü). Çağırmadan önce denetlemek 13 çağrıyı kaldırır.

Adım Adım Çalıştırma · İteratif Gezinme

Soru 11: Yığınla Kök Önde

Kök önde gezinmenin yığınlı sürümü A(B(D, E), C(–, F)) ağacında çalıştırılıyor. Yığın nasıl değişir, çıktı nedir?

ABCDEF

Kök yığına konur.

ABCDEF

A alınıp yazılır; önce sağ (C), sonra sol (B) itilir: sol üstte kalır.

ABCDEF

B alınıp yazılır; E ve D itilir.

ABCDEF

D yaprak: yazılır, itilen yok.

ABCDEF

E yazılır. B'nin alt ağacı bitti; sırada C bekliyor.

ABCDEF

C yazılır; sol çocuğu yok, yalnız F itilir.

ABCDEF

F yazılır; yığın boşaldı. Sonraki yigit_al NULL döner, döngü biter.

void kok_onde_d(agac_gost L) {
  agac_gost yigit[MAX_SIZE]; int ust = -1;
  if (L) yigit_ekle(&ust, L, yigit);
  while ((L = yigit_al(&ust, yigit))) {
    printf("%c", L->veri);
    if (L->sagcocuk) yigit_ekle(&ust, L->sagcocuk, yigit);
    if (L->solcocuk) yigit_ekle(&ust, L->solcocuk, yigit);
  }
}

Klasik Soru · Diğer Yordamlar

Soru 12: k. Düzeydeki Düğümler

k. düzeydeki (kök 1. düzey) düğüm sayısını döndüren özyinelemeli int duzey_say(agac_gost L, int k) yordamını yazın. A(B(D, E), C(–, F)) ağacında k = 1, 2, 3, 4 için ne döndürür?

Cevabı göster
int duzey_say(agac_gost L, int k) {
  if (!L || k < 1) return 0;
  if (k == 1) return 1;
  return duzey_say(L->solcocuk, k - 1)
       + duzey_say(L->sagcocuk, k - 1);
}

Sonuçlar: 1, 2, 3, 0 (programla doğrulandı). Her çağrıda k bir azalır; k = 1'e inen her dolu düğüm 1 katar. En kötü O(n) zaman, O(min(k, h)) yığın; kuyruk gerekmez.

Adım Adım Çalıştırma · Diğer Yordamlar

Soru 13: Küçük Kuyrukla Düzey Sırası

duzey_dolas, MAX_SIZE = 4 olan dairesel kuyrukla A(B(D, E), C(–, F)) ağacında çalıştırılıyor. Kuyruk yeterli mi, çıktı nedir?

0A123onarka

Kök kuyruğa: arka = 1. Dört gözlü dairesel kuyruk en çok 3 adres tutar.

0123on, arka

A alınır ve yazılır; kuyruk boşaldı.

01B2C3onarka

A'nın çocukları B ve C arkaya eklenir.

D0E12C3onarka

B alınır; D ve E eklenirken arka sarılır: D göz 0'a, E göz 1'e.

D0E1F23onarka

C alınır, F eklenir (göz 2). Kuyrukta D, E, F: kapasite tam doldu.

0E1F23onarka

D alınır (on sarıldı); çocuk yok.

0123on, arka

E ve F de alınır; on == arka: kuyruk boş, döngü biter.

void duzey_dolas(agac_gost L) {
  agac_gost k[MAX_SIZE];   /* kuyruk */
  int on = 0, arka = 0;
  if (!L) return;
  kuyruk_ekle(on, &arka, L, k);
  while ((L = kuyruk_al(&on, arka, k))) {
    printf("%c", L->veri);
    if (L->solcocuk)
      kuyruk_ekle(on, &arka, L->solcocuk, k);
    if (L->sagcocuk)
      kuyruk_ekle(on, &arka, L->sagcocuk, k);
  }
}

Çoktan Seçmeli · Diğer Yordamlar

Soru 14: SWAP Arada

cocukdegistir'de SWAP iki özyinelemeli çağrının arasına konmuştur. A(B(D, E), C) ağacına uygulanınca yeni ağacın kök ortada sırası nedir?

#define SWAP(x, y, t) ((t) = (x), (x) = (y), (y) = (t))
void arada(agac_gost L) {
  agac_gost p;
  if (L) {
    arada(L->solcocuk);
    SWAP(L->solcocuk, L->sagcocuk, p);
    arada(L->sagcocuk);
  }
}

B: B'de: önce D işlenir, takas B(E, D) yapar, sonra “sağ” yani yine D işlenir. A'da takas A(C, B) yapar ve sağdaki B ikinci kez işlenip B(D, E)'ye geri döner. Sonuç A(C, B(D, E)): C A D B E. Tam ayna (A) için SWAP çağrılardan önce ya da sonra olmalıdır (çalıştırılarak doğrulandı).

Klasik Soru · Sınav Sorusu

Soru 15: İki Gezinmeden Ağaç

Kök ortada sırası D B G E A C H F, kök sonda sırası D G E B H F C A olan ikili ağacı çizin ve kök önde sırasını yazın.

Cevabı göster ABCDEFGH
  • Kök sondanın sonu A → kök. Kök ortada A'nın solu D B G E, sağı C H F.
  • Sol taraf: kök sonda D G E B → kök B; solu D, sağı G E. G E içinde son E → E'nin sol çocuğu G.
  • Sağ taraf: H F C → kök C; kök ortada C'den önce harf yok → solu boş; sağı H F → F, sol çocuğu H.
  • Kök önde: A B D E G C F H (programla kurulup doğrulandı).

Çoktan Seçmeli · Özet

Soru 16: Ek Bellek Karşılaştırması

n = 2ᵏ − 1 düğümlü tam dolu ikili ağaçta yığınlı kök ortada gezinme ile kuyruklu düzey sırası gezinmenin ek bellekleri için hangisi doğrudur?

A: Yığında aynı anda en çok bir sol zincir, yani derinlik kadar adres bulunur: k = lg(n + 1) (15 düğümde 4 ölçüldü). Kuyrukta bir düzeyin tamamı birikir; son düzeyde 2ᵏ⁻¹ ≈ n/2 düğüm vardır. Çarpık ağaçta durum tersine döner: yığın O(n), kuyruk O(1).

Son

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