====== Arbori Binari de Căutare ======
Un **arbore binar de căutare (BST)** este o structură de date arborescentă în care,
pentru orice nod de valoare \(x\), toate valorile din subarborele stâng sunt
\(< x\), iar toate din cel drept sunt \(> x\). În cadrul acestui laborator vom
pune inegalitatea parțială pe subarborele stâng (\(\le x\)). Această
proprietate permite căutări eficiente, în medie în timp \(O(\log n)\), și
stă la baza multor algoritmi și structuri de date.
Reamintim definiția TDA-ului pentru un arbore binar abstract:
\( \text{Nil}: \mathrm{BTree} \)\\
\( \text{Node}: \mathbb{E} \times \mathrm{BTree} \times \mathrm{BTree} \to \mathrm{BTree} \)
unde \(\mathbb{E}\) este o [[https://en.wikipedia.org/wiki/Partially_ordered_set|mulțime parțial ordonată]].
Pentru simplitate vom folosi \(\mathbb{N}\), mulțimea numerelor naturale, însă putem lucra
cu orice mulțime peste care este definită o relație de ordine \(\le\).
==== Definiția operatorului \(\mathrm{isBST}\) ====
\( \mathrm{isBST} : \mathrm{BTree} \to \mathrm{Bool} \\
\mathrm{isBST}(t) = \mathrm{isBSTBetween}(t, -\infty, +\infty) \\
\mathrm{isBSTBetween} : \mathrm{BTree} \times \overline{\mathbb{E}} \times \overline{\mathbb{E}} \to \mathrm{Bool} \\
\mathrm{isBSTBetween}(\mathrm{Nil}, lo, hi) = \text{true} \\
\mathrm{isBSTBetween}(\mathrm{Node}(x,l,r), lo, hi) = (lo \le x \le hi)
\;\land\;
\mathrm{isBSTBetween}(l, lo, x)
\;\land\;
\mathrm{isBSTBetween}(r, x, hi). \)
unde \(\overline{\mathbb{E}} = \mathbb{E} \cup \{-\infty, +\infty\}\).
Elementele \(-\infty\) și \(+\infty\) extind domeniul astfel încât:
\( -\infty < x < +\infty,\forall x \in \mathbb{E}. \)
==== Exerciții ====
1. Scrieți axiomele pentru următorii operatori:
* $ {\mathrm{insert} : \mathbb{E} \times \mathrm{BTree} \to \mathrm{BTree} } $
* $ {\mathrm{min} : \mathrm{BTree} \to \mathbb{E} } $
* $ {\mathrm{max} : \mathrm{BTree} \to \mathbb{E} } $
2. Completați fragmentul de cod Python pentru calculul drumului mediu în găsirea unui element x
într-un Arbore Binar de Căutare construit pe baza operatorului $ {\mathrm{insert}} $ din exercițiul anterior:
import random
class Node:
def __init__(self, x):
self.x = x
self.left = None
self.right = None
def insert(root, x):
# TODO: inserați x în arbore
pass
def search_path_length(root, x):
# TODO: calculați lungimea drumului până la x
pass
def average_search_path(n):
"""Construiește un BST dintr-o permutare aleatoare și măsoară media."""
perm = list(range(1, n + 1))
random.shuffle(perm)
root = None
for x in perm:
root = insert(root, x)
lengths = [search_path_length(root, x) for x in perm]
return sum(lengths) / n
def experiment(trials=2000, n=100):
total = 0
for _ in range(trials):
total += average_search_path(n)
return total / trials
for n in [10, 20, 50, 100, 200, 500, 1000]:
avg = experiment(trials=1000, n=n)
print(f"n = {n} → lungime medie ≈ {avg:.3f}")
Rezultatul teoretic:
\(
E[L] = \tfrac{2 (n + 1)}{n} (H_{n+1} - 1) - 1
= \tfrac{2 (n + 1)}{n} (\tfrac{1}{2} + \tfrac{1}{3} + \dots + \tfrac{1}{n} + \tfrac{1}{n+1}) -1
\)
Cum ar putea fi îmbunătățit drumul mediu și care este acesta pentru un arbore echilibrat?
3. Demonstrați (prin inducție structurală) că următoarele păstrează invariantul \(\mathrm{isBST}\):
* $ {\mathrm{insert}} $
* $ {\mathrm{delete}} $
Soluțiile acestui laborator se găsesc [[https://ocw.cs.pub.ro/ppcarte/doku.php?id=aa:lab:sol:8|aici]]