Bölüm 10: Ağaçlar
Ç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?
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
- Ç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
- 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?
A'nın sol çocuğu B için çağrı; A'nın çerçevesi bekler.
B'nin solu NULL → 0 döndü (s = 0). Şimdi sağ çocuk D.
D'nin sol çocuğu E için çağrı: yığın en derin hâlinde, 5 çerçeve.
E yaprak: iki çocuk 0 → 1 + 0 = 1 döner.
D: s = 1, g = 0 (NULL) → 2.
B: s = 0, g = 2 → 3.
A'ya dönüldü, s = 3. Sağ çocuk C yapraktır → 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?
Kök yığına konur.
A alınıp yazılır; önce sağ (C), sonra sol (B) itilir: sol üstte kalır.
B alınıp yazılır; E ve D itilir.
D yaprak: yazılır, itilen yok.
E yazılır. B'nin alt ağacı bitti; sırada C bekliyor.
C yazılır; sol çocuğu yok, yalnız F itilir.
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?
Kök kuyruğa: arka = 1. Dört gözlü dairesel kuyruk en çok 3 adres tutar.
A alınır ve yazılır; kuyruk boşaldı.
A'nın çocukları B ve C arkaya eklenir.
B alınır; D ve E eklenirken arka sarılır: D göz 0'a, E göz 1'e.
C alınır, F eklenir (göz 2). Kuyrukta D, E, F: kapasite tam doldu.
D alınır (on sarıldı); çocuk yok.
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
- 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).