Curs 2- Agenda
Tipuri de date de nivel inalt
Liste liniare
Liste liniare ordonate
Stiva
Coada
tipul abstract (LLin, LLinOrd, Stiva, Coada)
implementare cu tablouri
implementare cu liste simplu inlantuite
Aplicatie la conversii de expresii
Liste liniare: tipul abstract LLin
obiecte
L = (e0,…, en-1), n ≥ 0, ei ∈ Elt (tipul abstract al elementelor)
operatii
listaVida()
intrare: nimic
iesire
() (lista cu zero elemente)
insereaza()
intrare:
L = (e0,…, en-1), k ∈ Nat, e ∈ Elt
iesire
L = (…ek-1, e, ek,…) daca 0 ≤ k ≤ n
eroare in caz contrar
LLin (continuare 1)
elimina()
intrare:
L = (e0,…, en-1), k ∈ Nat
Iesire
L = (…ek-1, ek+1…) daca 0 ≤ k ≤ n-1
eroare in caz contrar
alKlea()
intrare:
L = (e0,…, en-1), k ∈ Nat
Iesire
ek daca 0 ≤ k ≤ n-1
eroare in caz contrar
LLin (continuare 2)
poz()
intrare:
L = (e0,…, en-1), e ∈ Elt
iesire:
prima pozitie pe care apare e in L sau -1 daca e nu apare in L
parcurge()
intrare:
L = (e0,…, en-1), o procedura (functie) viziteaza()
iesire:
lista L in care toate elementele au fost procesate aplicand viziteaza()
LLin: implementare cu tablouri
reprezentarea obiectelor L = (e0,…, en-1)
L este o structura
un camp de tip tablou L.tab pentru memorarea elementelor
un camp L.ultim pentru memorarea pozitiei ultimului element
MAX-1 en-1
L.tab Elt[MAX] e0 … 0
L.ultim Nat
LLin: implementare cu tablouri: operatii
insereaza()
deplaseaza elementele de pe pozitiile k, k+1, … la dreapta cu o pozitie
insereaza e pe pozitia k
exceptii:
k<0, k > L.ultim+1 (k > n)
L.ultim = MAX
LLin: implementare cu tablouri: operatii
procedure insereaza(L, k, e)
if (k < 0 or k > L.ultim + 1) then throw “eroare”
if (L.ultim >= MAX) then throw “eroare”
for j ← L.ultim downto k do L.tab[j+1] ← L.tab[j]
L.tab[k] ← e
L.ultim ← L.ultim + 1 end
timpul de executie: O(n)
LLin: implementare cu tablouri: operatii
parcurge
procedure parcurge(L, viziteaza()) for i ←0 to L.ultim do
viziteaza(L.tab[i]) end
daca viziteaza() proceseaza un element in
O(1), atunci parcurge proceseaza lista in O(n)
LLin: implementarea cu liste inlantuite
reprezentarea obiectelor L = (e0,…, en-1)
L.prim
e0 e1 … en-1
L.ultim
L structura cu doua campuri
pointer la primul element
pointer la ultimul element
un nod p are doua campuri:
unul pentru memorarea informatiei: p->elt = ei
si unul pentru nodul succesor: p->succ
LLin: implementarea cu liste inlantuite
insereaza()
parcurge elementele 0, 1,…, k-1
insereaza un nou dupa k-1
creeaza nodul
memoreaza informatii
reface legaturi
exceptii
lista vida
k=0
k=n
k<0, k > n
LLin: implementarea cu liste inlantuite
ek-1
e
L.prim L.ultim
e
e e0
L.prim
LLin : implementarea cu liste inlantuite
procedure insereaza(L, k, e) if (k<0) then throw “error”
new(q); q->elt ← e
if (k = 0 or L.prim = NULL) then q->succ ← L.prim
L.prim ← q
if (L.ultim = NULL) then L.ultim ← q else p ← L.prim; j ← 0
while (j<k-1 and p ≠ L.ultim) do p ← p->succ; j ← j+1
if (j < k-1) then throw “error”
q->succ ← p->succ; p->succ ← q
if (p = L.ultim) then L.ultim ← q end
LLin: aplicatie
linie poligonala de puncte
Punct structura cu doua campuri x si y
crearea unei liste
procedure creeazaLista(L) L ← listaVida();
//citeste n
for i ← 0 to n-1 do //citeste p.x, p.y insereaza(L, i, p) end
atentie: timpul de executie depinde de implementare
LLin: aplicatie
multiplica cu 2 coordonatele unui punct procedure ori2Punct(p)
p.x ← p.x * 2 p.y ← p.y * 2 end
multiplica cu 2 coordonatele unei linii poligonala
procedure ori2Linie(L)
parcurge(L, ori2Punct()) end
LLin: aplicatie
translateaza punct
procedure trPunct(p, dx, dy) p.x ← p.x + dx
p.y ← p.y + dy end
translateaza linie poligonala procedure trLinie(L, dx, dy)
parcurge(L, trPunct(), dx, dy) end
… totusi presupune modificarea procedurii parcurge
Liste liniare ordonate: LLinOrd
obiecte
L = (e0,…, en-1), n ≥ 0, ei ∈ Elt, e0<…< en-1
operatii
listaVida()
insereaza()
intrare:
L = (e0,…, en-1), e ∈ Elt
iesire
L = (…ek-1, e, ek,…) daca ek-1 < e < ek (e-1 = -∞, en = +∞ )
LLinOrd
elimina()
intrare:
L = (e0,…, en-1), e ∈ Elt
Iesire
L = (…ek-1, ek+1…) daca e = ek
eroare in caz contrar
alKlea()
parcurge()
LLinOrd
poz()
intrare:
L = (e0,…, en-1), e ∈ Elt
iesire:
pozitia pe care apare e in L sau -1 daca e nu apare in L
…
LLinOrd: implementarea cu tablouri
cautare binara
function Poz(L, e) begin
p ← 0; q ← L.ultim m ← [(p+q)/2]
while (L.tab[m] != e && p < q) do if (e < L.tab[m])
then q ← m-1 else p ← m+1 m ← [(p+q)/2]
if (L.tab[m] = e) then return m
else return -1;
LLinOrd: implementarea cu tablouri
cautare binara
timpul de executie O(log n)
demonstratie:
LLinOrd: implementarea cu liste inlantuite
cautare binara => cautare liniara
timpul de executie O(n) dar mai mic decat in cazul neordonat
Tipul abstract Stiva
obiecte
liste in care se cunoaste vechimea elementelor introduse (liste LIFO)
operatii
stivaVida()
intrare: nimic
iesire
lista vida
push()
intrare
S ∈ Stiva, e ∈ Elt
iesire
S la care s-a adaugat e ca ultimul element introdus (cel cu vechimea cea mai mica)
Tipul abstract Stiva (continuare 1)
pop()
intrare
S ∈ Stiva
iesire
S din care s-a eliminat ultimul element introdus (cel cu vechimea cea mai
mica)
eroare daca S este vida
esteVida()
intrare
S ∈ Stiva
isesire
true daca S este vida
Tipul abstract Stiva (continuare 2)
top()
intrare
S ∈ Stiva
iesire
ultimul element introdus (cel cu vechimea cea mai mica)
eroare daca S este vida
Stiva: implementarea cu liste liniare
push(S, e) = insereaza(S, 0, e) pop(S) = elimina(S, 0)
top(S) = alKlea(S, 0) sau
push(S, e) = insereaza(S, lung(S), e) pop(S) = elimina(S, lung(S)-1)
top(S) = alKlea(S, lung(S)-1)
Stiva: implementarea cu tablouri
reprezentarea obiectelor
MAX-1 en-1
S.tab Elt[MAX] e0 … 0
S.virf n-1
implementarea operatiilor
push()
procedure push(S, e) if (S.virf = MAX-1) then throw “eroare”
S.virf ← S.virf+1 S.tab[virf] ← e
Stiva: implementarea cu liste inlantuite
reprezentarea obiectelor
e0 en-1
en-2
. . .
S
Stiva: implementarea cu liste inlantuite
implementarea operatiilor
push()
procedure push(S, e) new(q)
q->elt ← e q->succ ← S S ← q
endpop()
procedure pop(S)
if (S = NULL) then throw “eroare”
q ← S
S ← S->succ delete(q)
end
Tipul abstract Coada
obiecte
liste in care se cunoaste vechimea elementelor introduse (liste FIFO)
operatii
coadaVida()
intrare: nimic
iesire
lista vida
insereaza()
intrare
C ∈ Coada, e ∈ Elt
iesire
C la care s-a adaugat e ca ultimul element introdus (cel cu vechimea
Tipul abstract Coada (continuare 1)
elimina()
intrare
C ∈ Coada
iesire
C din care s-a eliminat primul element introdus (cel cu vechimea cea mai
mare)
eroare daca C este vida
esteVida()
intrare
C ∈ Coada
isesire
true daca C este vida
Tipul abstract Coada (continuare 2)
citeste()
intrare
C ∈ Coada
iesire
primul element introdus (cel cu vechimea cea mai mare)
eroare daca C este vida
Coada: implementarea cu liste liniare
insereaza(C, e) = LLin.insereaza(C, lung(C), e) elimina(C) = LLin.elimina(C, 0)
citeste(C) = LLin.alKlea(C, 0)
Coada: implementarea cu tablouri
reprezentarea obiectelor
C.tab Elt[nMax] …
MAX-1 C.prim p
… …
C.ultim
q e0 en-1
C.tab Elt[nMax] …
MAX-1 C.ultim q
… …
C.prim
p
en-1 e0 ei
C are patru campuri: C.tab, C.prim, C.ultim,
Coada: implementarea cu tablouri
implementarea operatiilor
insereaza()
procedure insereaza(C, e) if (C.nrElem = MAX-1) then throw “error”
C.ultim ← (C.ultim + 1) % MAX C.tab[C.ultim] ← e
C.nrElem ← C.nrElem + 1 end
Coada: implementarea cu liste inlantuite
reprezentarea obiectelor
C.prim
e0 e1 … en-1
C.ultim
Coada: implementarea cu liste inlantuite
implementarea operatiilor
insereaza()
procedure insereaza(C, e) new(q)
q->elt ← e
q->succ ← NULL
if (C.ultim = NULL) then C.prim ← q
C.ultim ← q
else C.ultim->succ ← q C.ultim ← q
end
Aplicatie: notatia postfixata a expresiilor
notatia infixata a + b
a + (b * 2)
notatia postfixata a b +
b 2 * a +
reguli de precedenta a + b * 2
reguli de asociere 7 / 3 * 2
la stanga (7 / 3) * 2
la dreapta 7 / (3 * 2)
Translatarea infix -> postfix
procedure convInfix2Postfix(infix, postfix) /* infix si postfix sunt cozi */
begin
S ← stivaVida()
while (!esteVida(infix)) do
citeste(infix, x); elimina(infix);
if (x este operand) then insereaza(postfix,x) else if (x = ‘)’)then
while (top(s) ≠ ‘(‘) do
insereaza(postfix, top(S)); pop(S) pop(S)
else
while (priorit(top(S)) >= priorit(x)) do insereaza(postfix, top(S)); pop(S)
push(S,x)
while (!estevida(S)) do
insereaza(postfix, top(S)); pop(S)
Evaluare a expresiilor postfixate
function valPostfix(postfix) begin
S ← stivaVida()
while (!esteVida(postfix)) do
citeste(postfix, x); elimina(postfix) if (x este operand)
then push(S, x)
else drp ← top(S); pop(S) stg ← top(S); pop(S) val ← stg op(x) drp push(S, val)
val = top(S); pop(S) return val
end