Curs 3 - Agenda
recursie
arbori binari
aplicatie: reprezentarea expresiilor ca arbori
coada cu prioritati si max-heap
colectii de multimi disjuncte si “union-find”
Subprograme recursive
subprogramul f() apeleaza direct
subprogramul g() daca blocul care defineste f() include un apel al lui g()
subprogramul f() apeleaza indirect
subprogramul g() daca f() apeleaza direct un subprogram h() si h() apeleaza direct sau
indirect g()
f() este definit recursiv daca se autoapeleaza direct sau indirect
Subprograme recursive: Fibonacci
function fibRec(n) if (n <= 1)
then return n
else return fibRec(n-1) + fibRec(n-2) end
fibRec(5) fibRec(4)
fibRec(3) fibRec(2)
fibRec(3)
fibRec(2) fibRec(1)
Fibonacci – nerecursiv
function fib(n)
if (n<=1) return n
// k = 0
fk_1 ← 0 // fib[k-1]
fk ← 1 // fib[k]
for k ← 2 to n do fk_2 ← fk_1
fk_1 ← fk
fk ← fk_2 + fk_1 return fk;
end
Functii recursive: conversie binara
procedure convert(x) 1.if (x != 0)
2.then convert(x/2) 3. print(x % 2) }
convert(12) convert(6)
convert(3)
convert(1)
11
1 110 1100
0 1 3 3 3 6 3
Functii recursive: turnurile din Hanoi
sursa intermediar destinatie
sursa intermediar destinatie
Functii recursive: turnurile din Hanoi
procedure muta(n, a, b, c) // a = sursa
// b = destinatia // c = intermediar
if (n = 1)
then print(a, “->”, b);
else muta(n-1, a, c, b);
print(a, “->”, b);
muta(n-1, c, b, a);
Tipul de date abstract ArbBin
¾ obiecte : arbori binari
• un arbore binar este o colectie de noduri cu proprietatile:
1.orice nod are 0, 1 sau 2 succesori (fiii, copiii)
2.orice nod, exceptand unul singur – radacina, are un singur nod predecesor (tata, parintele)
3.radacina nu are predecesori
4.fiii sunt ordonati: fiul stang, fiul drept (daca un nod are un singur fiu, trebuie mentionat care)
5.nodurile fara fii formeaza frontiera arborelui
Arbori binari: exemplu
C
M D
K A
E G
F I L
H
B
Arbori binari: definitia recursiva:
arborele cu nici un nod (vid) este arbore binar
daca v este un nod si t1, t2 sunt arbori binari atunci arborele care are pe v ca
radacina, t1 subarbore stang al radacinii si t2 subarbore drept al radacinii, este arbore binar
t2 t1
v
ArbBin: operatii
insereaza()
intrare:
un arbore binar t, adresa unui nod cu cel mult un fiu (tatal noului nod), tipul fiului adaugat (stinga, dreapta) si
informatia e din noul nod
iesire
arborele la care s-a adaugat un nod ce
memoreaza e; noul nod nu are fii
ArbBin: inserare
C
M D
K A
E G
F I L
H X B
Y
ArbBin: eliminare
elimina()
intrare:
un arbore binar t, adresa un nod fara fii si adresa nodului-tata
iesire
arborele din care s-a eliminat nodul de
pe frontiera dat
ArbBin: eliminare
C
L
M D
K A
E G
F I H
B
ArbBin : parcurgere preordine
parcurgePreordine()
intrare
un arbore binar t, o procedura viziteaza()
iesire
arborele binar t dar cu nodurile procesate cu viziteaza()in ordinea:
radacina (R)
subarborele stanga (S)
subarborele dreapta (D)
ArbBin : parcurgere preordine - exemplu
C
L
M D
K A
E G
F I H
B
C, E, K, B, H, A, L, F, G, M, D, I
ArbBin : parcurgere inordine
parcurgeInordine()
intrare
un arbore binar t, o procedura viziteaza()
iesire
arborele binar t dar cu nodurile procesate cu viziteaza()in ordinea S R D
ArbBin : parcurgere inordine - exemplu
C
L
M D
K A
E G
F I H
B
K, H, B, E, L, A, F, C, M, G, I, D
ArbBin: parcurgere postordine
parcurgePostordine()
intrare
un arbore binar t, o procedura viziteaza()
iesire
arborele binar t dar cu nodurile procesate cu viziteaza()in ordinea S D R
ArbBin
:parcurgere BFS
parcurgeBFS()
intrare
un arbore binar t, o procedura viziteaza()
iesire
arborele binar t dar cu nodurile procesate cu viziteaza()in ordinea BFS (pe
nivele)
ArbBin: parcurgere BFS - exemplu
C
L
M D
K A
E G
F I H
B
ArbBin : implementare cu structuri inlantuite
reprezentarea obiectelor C
E G
B H
K A
L F
M D
I
ArbBin : structura unui nod
un nod v este o structura cu trei campuri:
v->inf /* informatia memorata in nod */
v->stg /* adresa fiului stanga */
v->drp /* adresa fiului dreapta */
Arbori binari: parcurgePreordine()
procedure parcurgePreordine(v) if (v = NULL)
then return
else viziteaza(v)
parcurgePreordine(v->stg) parcurgePreordine(v->drp) end
Arbori binari: implementarea parcurgerii BFS
C
M D
K A
E G
Arbori binari: implementarea parcurgerii BFS
procedure parcurgeBFS(t) begin
if (t = NULL) then return
else C ← (t)
while (not esteVida(C)) citeste(C, v)
viziteaza(v) elimina(C)
if (v→stg ≠ NULL)
then insereaza(C, v->stg) if (v→drp ≠ NULL)
then insereaza(C, v->drp) end
Aplicatie: expresii intregi
Expresii intregi
definitie
exemple
Reprezentarea expresiilor ca arbori
similaritati intre cele doua definitii
arborele asociat unei expresii
notatiile pref-, in- si postfixate si parcurgeri ale arborilor
Definitia expresiilor intregi
<int> ::= ... –2 | -1 | 0 | 1 | 2 ...
<expr_int> ::= <int>
| <exp_int> <op_bin> <exp_int>
| (<exp_int>)
<op_bin> ::= + | − | * | / | %
reguli de precedenta
12-5*2 este (12-5)*2 sau 12-(5*2)
reguli de asociere
15/4/2 este (15/4)/2 sau 15/(4/2)? 15/4*2 este (15/4)*2 sau 15/(4*2)?
Expresiile reprezentate ca arbori
-12 + 17 * 5 – (43 + 34 / 21 * 66)
−
+ +
* *
/ -12
17 5 66
43
Notatiile postfixate si prefixate
notatia postfixata se obtine prin parcurge postordine
-12 17 5 * + 43 34 21 / 66 * + -
notatia prefixata se obtine prin parcurge preordine
- + -12 * 17 5 + 43 * / 34 21 66
−
+ +
* *
/ -12
17 5 66
43
Coada cu prioritati: tip de data abstract
obiecte de tip data: structuri de date in care elementele sunt numite atomi; orice atom un camp-cheie numit prioritate
Coada cu prioritati:operatii
citeste
intrare: o coada cu prioritati C
iesire: atomul din C cu cheia cea mai mare
elimina
intrare: o coada cu prioritati C
iesire: C din care s-a eliminat atomul cu cheia cea mai mare
insereaza
intrare: o coada cu prioritati C si un atom at
iesire: C la care s-a adaugat at
maxHeap
arbori binari completi cu proprietatea: pentru orice nod, cheia din acel nod este mare decit sau egala cu cheile din nodurile fii
exemplu
12
3 4
7 1
9 8
maxHeap: eliminarea
12
3 4
7 1
9 8
5 2
maxHeap: inserarea
12
3 4
7 1
9 8
5 2
10
maxHeap: implementarea cu tablouri
(∀k) 1 ≤ k ≤ n-1 ⇒ a[k] ≤ a[(k-1)/2]
8 7
6 5
4 3
2 1
0
12
3 4
7 1
9 8
5 2
0
2 1
3 4 5 6
12 9 8 7 1 3 4 5 2
maxHeap: inserare
procedure insereaza(a, n, cheie) begin
n ← n+1
a[n-1] ← cheie j ← n-1
heap ← false
while ((j > 0) and not heap) do k ← [(j-1)/2]
if (a[j] > a[k])
then swap(a[j], a[k])
maxHeap - elimina
procedure elimina(a, n) begin
a[0] ← a[n-1]
n ← n-1 j ← 0
heap ← false
while ((2*j+1 < n) and not heap) do k ← 2*j+1
if ((k < n-1) and (a[k] < a[k+1])) then k ← k+1
if (a[j] < a[k])
then swap(a[j], a[k]) j ← k
else heap ← true end
maxHeap: timp de executie
inaltime (adancime) arbore = lungimea celui mai lung drum de la radacina la frontiera
lungime drum = numar arce
n =2k+1-1
inaltime arbore = k = log (n+1)-1
operatiile inserare/eliminare necesita timpul O(inaltime abore) = O(log n)
0
Colectii de multimi disjuncte: tip de data abstract
obiecte: colectii de submultimi disjuncte (partitii) ale unei multimi univers
operatii:
find()
intrare: o colectie C, un element x din univers
iesire: submultimea din C la care apartine x
union()
intrare: o colectie C, doua elemente x si y din univers
iesire: C in care componentele lui x si resp. y sint reunite
single()
intrare: o colectie C, un element x din univers
iesire: C la care componenta lui x are pe x ca unic element
Colectii de multimi disjuncte: “union-find”
structura “union-find”
multimea univers = {0,1, ..., n-1}
submultime = arbore
colectie = padure
reprezentarea unei paduri prin legatura parinte
2 6
1 3 0
5
8 7
9
Colectii de multimi disjuncte: “union-find”
function find(C, i) begin
temp ← i
while (parinte[temp] >= 0) do temp ← parinte[temp]
return temp end
procedure union(C, i, j) begin
ri ← find(i) rj ← find(j) if (ri ≠ rj)
then parinte[rj] ← ri