Daraxt chuqurligi
Binar daraxt berilgan. Uning maksimal chuqurligini toping.
Maksimal chuqurlik — ildizdan eng chuqur bargigacha bo'lgan tugunlar soni.
Ildizdan [15] yoki [7] gacha: [3] → [20] → [15] — 3 ta tugun. Bu maksimal yo'l.
Asosiy g'oya: rekursiya
Ildizning maksimal chuqurligi qanday? U 1 (ildizning o'zi) va chap yoki o'ng kenja daraxtning maksimal chuqurligidan kattasi yig'indisi:
Base case: bo'sh daraxt uchun chuqurlik 0.
FUNCTION MAX_DEPTH(node)
IF node = NULL
RETURN 0
left_depth = MAX_DEPTH(node.left)
right_depth = MAX_DEPTH(node.right)
RETURN 1 + MAX(left_depth, right_depth)
Bu postorder rekursiya: avval kenja daraxtlar hisoblanadi, so'ng natijalar birlashtirilib qaytariladi.
Bosqichma-bosqich dry run
Rekursiv chaqiruvlar zanjirini kuzatamiz:
MAX_DEPTH(3):
MAX_DEPTH(9):
MAX_DEPTH(NULL) = 0 (9 ning chap bolasi)
MAX_DEPTH(NULL) = 0 (9 ning o'ng bolasi)
return 1 + MAX(0, 0) = 1
MAX_DEPTH(20):
MAX_DEPTH(15):
MAX_DEPTH(NULL) = 0
MAX_DEPTH(NULL) = 0
return 1 + MAX(0, 0) = 1
MAX_DEPTH(7):
MAX_DEPTH(NULL) = 0
MAX_DEPTH(NULL) = 0
return 1 + MAX(0, 0) = 1
return 1 + MAX(1, 1) = 2
return 1 + MAX(1, 2) = 3
Javob: 3
Har tugun faqat bir marta ko'riladi. Har rekursiv chaqiruv O(1) ish bajaradi.
Iterativ yondashuv: BFS
Rekursiya o'rniga BFS bilan qavatma-qavat sanash. Qavatlar soni — maksimal chuqurlik.
FUNCTION MAX_DEPTH_BFS(root)
IF root = NULL
RETURN 0
queue = [root]
depth = 0
WHILE queue bo'sh emas
depth = depth + 1
level_size = navbat hajmi
FOR i = 0 DAN level_size-1 GACHA
node = queue dan DEQUEUE
IF node.left ≠ NULL
queue ga node.left ENQUEUE
IF node.right ≠ NULL
queue ga node.right ENQUEUE
RETURN depth
Dry run:
queue: [3] depth: 0
Iteratsiya 1: level_size=1
DEQUEUE 3 → 20, 9 qo'shildi
queue: [9, 20] depth: 1
Iteratsiya 2: level_size=2
DEQUEUE 9 → bolasi yo'q
DEQUEUE 20 → 15, 7 qo'shildi
queue: [15, 7] depth: 2
Iteratsiya 3: level_size=2
DEQUEUE 15 → bolasi yo'q
DEQUEUE 7 → bolasi yo'q
queue: [] depth: 3
Javob: 3
Vaqt va xotira murakkabligi
| Yondashuv | Vaqt | Xotira | Eslatma |
|---|---|---|---|
| Rekursiv DFS | O(n) |
O(h) |
Call stack chuqurligi |
| Iterativ BFS | O(n) |
O(w) |
Eng keng qavat |
n — tugunlar soni, h — balandlik, w — eng keng qavat.
Muvozanatlangan daraxtda: rekursiv O(log n) xotira, BFS O(n/2) = O(n) xotira — rekursiv afzalroq.
Muvozanatsiz (zanjir) daraxtda: rekursiv O(n) xotira (stack overflow xavfi!), BFS O(1) xotira — BFS afzalroq.
Minimal chuqurlik
Ba'zan ildizdan eng yaqin barggacha bo'lgan yo'l so'raladi — minimal chuqurlik.
Maksimal chuqurlik: 3 (1 → 2 → 4).
Minimal chuqurlik: 2 (1 → 3).
Muhim farq: [2] ning faqat chap bolasi bor. [2] barg emas — uning bolasi bor. Minimal chuqurlik bargga bo'lgan eng qisqa yo'l.
FUNCTION MIN_DEPTH(node)
IF node = NULL
RETURN 0
// Bitta bolasi bo'lgan tugun barg hisoblanmaydi
IF node.left = NULL
RETURN 1 + MIN_DEPTH(node.right)
IF node.right = NULL
RETURN 1 + MIN_DEPTH(node.left)
RETURN 1 + MIN(MIN_DEPTH(node.left), MIN_DEPTH(node.right))
Nima uchun faqat 1 + MIN(left, right) emas? Agar chap bola bo'lmasa, MIN_DEPTH(NULL) = 0 qaytaradi — bu noto'g'ri, chunki NULL barg emas.
Edge case'lar
Bo'sh daraxt. root = NULL → return 0. Avval tekshirilishi kerak.
Bitta tugunli daraxt (faqat ildiz). Chap va o'ng NULL → 1 + MAX(0, 0) = 1. To'g'ri.
Faqat chap yoki o'ng shox. Zanjir ko'rinishidagi daraxt: 1 → 2 → 3 → 4. Chuqurlik 4. Rekursiya har qadam 1 + MAX(0, chuqurlik) hisoblaydi.
Muvozanatsiz daraxt. Chuqur shox maksimumni belgilaydi — bu to'g'ri ishlaydi.
Note
chuqurlik va balandlik atamalari ba'zan aralashtiriladi. Bu masalada "maksimal chuqurlik" so'ralsa ham, aslida ildizning balandligi + 1 hisoblanadi. Ko'p platformalarda "maximum depth = number of nodes along the longest path" deyiladi — bu tugunlar soni, qirralar soni emas.
Masalaning kengaytirilgan varianti
Muvozanatlangan daraxtni tekshirish. Har tugun uchun chap va o'ng kenja daraxt balandliklari farqi 1 dan oshmasligini tekshirish — chuqurlik rekursiyasining kengaytmasi.
FUNCTION IS_BALANCED(node)
IF node = NULL
RETURN TRUE
left_h = HEIGHT(node.left)
right_h = HEIGHT(node.right)
IF ABS(left_h - right_h) > 1
RETURN FALSE
RETURN IS_BALANCED(node.left) AND IS_BALANCED(node.right)
Bu O(n²) — har tugun uchun balandlik hisoblanadi. Optimallashtirilgan versiyada balandlik va muvozanatlilik bir rekursiyada birgalikda hisoblanadi.
Xulosa
Maksimal chuqurlik — rekursiyaning klassik namunasi. Har tugun o'z kenja daraxtlarining chuqurligini so'raydi va birini qo'shib qaytaradi.
Ikkita yondashuv: rekursiv DFS (kod sodda, xotira O(h)) va iterativ BFS (qavatlarni sanash, xotira O(w)). Muvozanatlangan daraxtda DFS afzal; katta muvozanatsiz daraxlarda BFS stack overflow xavfidan xoli.
Asosiy tuzilma — return 1 + MAX(left, right) — daraxt masalalarida qayta-qayta uchraydi: balandlik hisoblash, muvozanatni tekshirish, eng uzun yo'l topish.