Documente Academic
Documente Profesional
Documente Cultură
_______________________________________________________________________________
V. TEHNICI DE CAUTARE
V.1. Introducere n tehnicile de cutare
V.1.1.CUTARE SECVENTIAL
Cea mai simpl metod de cutare este cutarea secvenial. O metod simpl de stocare a
informaiei este stocarea nregistrrilor ntr-o tabel. Cnd o nou nregistrare este inserat, acesta se
adaug n poziia dorit, cnd trebuie efectuat o cutare, tabela este parcurs secvenial.
Cutarea secvenial este cea mai simpl metod de cutare a unei nregistrri ntr-o tabel
________________________________________________________________________________
170
Structuri de date i algoritmi
_______________________________________________________________________________
PROCEDURE INSERARE;
BEGIN
WRITE('Introducei elementul pe care dorii s-l inserai:');
READLN(g);
T[nr+1]:=g; { nr numrul de elemente din tablou }
END;
In cazul operaiei de tergere la nceput primul element din tabel este ters, iar celelalte
elemente se vor translata fiecare cu o poziie n sus n tabel. Un algoritm general pentru cutare
secvenial este prezentat mai jos.
Avem un vector neordonat T avnd MAX (MAX >= 1) elemente. Acest algoritm caut n
vectorul T elementul particular avnd valoarea X. Funcia returneaz indexul elementului vector
dac cutarea este cu succes altfel returneaz 0.
Secvena de instruciuni n Pseudocod este:
k := 1;
CTTIMP k <= MAX EXECUT
DAC T[k] = X
ATUNCI
@ returneaz k; {cutare cu succes}
EXIT;
ALTFEL
k := k + 1;
SFDAC
SFCT
@ returneaz 0; {cutare cu insucces}
________________________________________________________________________________
171
Structuri de date i algoritmi
_______________________________________________________________________________
Exemplul 4.1.
Function CAUTARE _SECVENTIALA ( T , j , X ) : integer ;
Begin
k := 1 ; { k - elementul cu care parcurgem tabela }
OK := false
while ( not OK ) and ( k <= j ) do { j - numrul de elemente din tabela T }
begin
if T [ k ] = X then { X cheia cutat }
begin
OK := true ;
CAUTARE_SECVENTIALA := k ;
end ;
exit
else
k := k + 1 ;
end;
CAUTARE_SECVENTIALA := 0 ;
end ;
unde pi reprezint probabilitatea ca informaia a-i-a s fie cutat, iar nri reprezint numrul de
operaii necesar accesrii informaiei a-i-a. Probabilitatea ca o dat s fie cutat poate fi exprimat
prin raportul:
nr _ de _ cautari _ al _ datei _ i
pi (5.2)
nr _ total _ de _ cautari
Pentru o cutare cu succes, dac presupunem c probabilitatea de cutare a unei nregistrri
particulare este aceeai cu probabilitatea de cutare a altor nregistrri, atunci numrul general de
comparaii este:
________________________________________________________________________________
172
Structuri de date i algoritmi
_______________________________________________________________________________
n n 1
1 1 2 n
n
n 1
2
(5.3)
ALOS i
i 1 n n n 2
n cazul n care probabilitatea de accesare a datelor din tabel nu este echiprobabil, atunci
cea mai eficient metod de organizare a datelor este cea n ordine descresctoare a probabilitilor
de cutare, datele cele mai probabile a fi cutate fiind dispuse la nceputul tabelei. S dovedim
aceast afirmaie:
- fie datele organizate ntr-o tabel n ordinea descresctoare a probabilitilor de cutare, i
anume:
astfel nct:
p1 p 2 p i p n (5.4)
unde i j . S presupunem c exist o alt organizare a datelor, unde acestea nu sunt organizate n
tabel n ordinea descresctoare a probabilitilor de cutare (5.3), i s msurm performana
ALOS a algoritmului de cutare. Este suficient s presupunem c exist o simpl permutare a
datelor, i anume c avem permutate Datai cu Dataj n tabel. n aceast situaie performana
algoritmului de cutare este:
n n
ALOS 2 pi nri p i i 1 p1 2 p 2 i p j j p i n p n
i 1 i 1
Concluzia este evident, organizarea datelor ntr-o tabel pentru a avea cea mai bun
performan media a operaiei de cutare este conform cu (5.4), adic datele trebuie organizate n
ordine descresctoare a probabilitii de cutare.
173
Structuri de date i algoritmi
_______________________________________________________________________________
Program cautare_in_tabel ;
const
MAX=100;
type
tablou = array [1..MAX] of integer;
var
T : tablou ;
d , nr , k , g , i , j : integer ;
a : char ;
Procedure TESTARE ;
begin
if nr > MAX then begin
{ nr numrul elementelor din tabel }
{ MAX numrul maxim de elemente }
write ( ' Depire capacitate ' ) ;
delay ( 4000 ) ;
halt ;
end ;
end ;
Procedure INSERARE ;
begin
write ( ' Introducei elementul de inserat: ' ) ;
readln ( g ) ; { g elementul care se nsereaz }
for k := nr downto 1 do
T[ k+1 ] := T [ k ] ;
T[ 1 ] := g ;
writeln ( ' Tabloul este: ' ) ;
for i := 1 to (nr + 1) do
writeln ( ' T[ ' , i , ' ]= ' , T[ i ] ) ;
readln ;
end ;
Procedure STERGERE ;
begin
write ( 'Introducei poziia elementului de sters: ' ) ;
readln ( d ) ; { d reprezint poziia elementului care va fi ters }
for k := d+1 to nr do
T [ k-1 ] := T [ k ] ;
writeln ( ' Tabloul este : ' ) ;
for i := 1 to ( nr-1 ) do
writeln ( ' T [ ' , i , ' ]= ' , T [ i ] ) ;
________________________________________________________________________________
174
Structuri de date i algoritmi
_______________________________________________________________________________
readln ;
end ;
Procedure CAUTARE ;
var
ok : boolean ;
h : integer ;
begin
write ( ' Introducei elementul cutat : ' ) ;
readln ( h ) ; { h elementul cutat }
ok := false ;
for i := 1 to nr do
begin
if T[ i ] = h then
begin
ok := true;
writeln ( ' Elementul cutat se afl pe poziia : ' , i ) ;
end ;
end ;
if not ok then
writeln ( ' Elementul cutat nu exist n tablou ! ' ) ;
readkey ;
end ;
BEGIN
clrscr ;
write ( ' Introducei nr. de elemente dorite : ' ) ;
readln ( nr ) ;
TESTARE ;
for i := 1 to nr do
begin
write ( ' T[ ' , i , ' ] = ' ) ;
readln ( T[ i ] ) ;
end ;
repeat
clrscr ;
writeln ( ' Apsai tasta dorit : ' ) ;
writeln ( ' 0 : Pentru nserare n tablou ' ) ;
writeln ( ' 1 : tergere n tablou ' ) ;
writeln ( ' 2 : Cutare n tablou ' ) ;
writeln ( Pentru ieire din program apsai tasta Esc ) ;
a := readkey ;
case a of
' 0 ' : INSERARE ;
' 1 ' : STERGERE;
' 2 ' : CAUTARE ;
________________________________________________________________________________
175
Structuri de date i algoritmi
_______________________________________________________________________________
end ;
until a = # 27 ;
END.
Numrai elementele pozitive, negative i nenule ale unei liste ntr-o funcie care dup
apelare, returneaz un pointer la un vector cu trei componente, ce stocheaz rezultatele parcurgerii
listei.
Program numara ;
type
plista = ^ lista ;
lista =record
b : integer ;
paue : plista ;
end ;
vec = array [ 1..3 ] of byte ;
pv = vec ;
var
cp1 : plista ;
i, n : integer ;
vect : vec ;
pvec : pv ;
176
Structuri de date i algoritmi
_______________________________________________________________________________
begin
plucru := vect ;
for i := 1 to 3 do
plucru ^[ i ] := 0 ;
while p1 < > NIL do
begin
if p1 ^. b > 0 then
plucru ^ [ 1 ] := plucru ^[ 1 ] + 1
else
if p1 ^.b < 0 then
plucru ^ [ 2 ] := plucru ^[ 2 ] + 1
else
plucru ^ [ 3 ] := plucru ^[ 3 ] + 1 ;
p1 := p1 ^.paue ;
end ;
numr := plucru ;
end ;
BEGIN
write (' Introduceti numrul de elemente ale listei : ') ;
readln (n) ;
cp1 := creare (n) ;
pvec := numr (cp1) ;
writeln ;
END.
1. Dac toate cheile de cutare sunt echiprobabile, care este deviaia standard a numrului de
comparaii efectuate ntr-o cutare secvenial cu succes ntr-un tabel cu N nregistrri ?
2. Presupunem c dorii s cutai ntr-un fiier voluminos ,nu dup criteriul egalitii, ci pentru a
gsi 1000 de nregistrri cele mai apropiate unei chei date, n sensul c aceste 1000 de
nregistrri au cea mai mic valoare a lui d (Ki,K) pentru o funcie d de distan dat. Care
structur de date este cea mai adecvat pentru o asemenea cutare secvenial ?
3. Fiind date dou succesiuni < X1 , X2 , , Xn> i < Y1 , Y2 , , Yn> de numere reale, care
permutare a1*a2**an a indiciilor va determina valoarea maxim al lui (Xi * Yai)? Dar
valoarea minim ?
4. Un programator dorete s testeze dac n condiii date snt sau nu simultan ndeplinite. (De
exemplu, el poate dori s testeze dac simultan este adevrat ca x > 0 si y < z*z, dar nu este
evident care dintre condiii trebuie testat prima). S presupunem c sunt necesare T i uniti de
________________________________________________________________________________
177
Structuri de date i algoritmi
_______________________________________________________________________________
6. Dac X este un vector cu n componente reale, scriei secvene de instruciuni pentru a obine
urmtoarele transformri ( fr a folosi un vector suplimentar ) :
a ) ( X1 , X2 , , Xn ) ( Xn , X1 , X2 , , Xn-1 )
b ) ( X1 , X2 , , Xn ) ( Xn , Xn-1 , Xn-2 , , X2 ,X1 )
c ) ( X1 , X2 , , Xn ) ( X i1 ,Xi2 , , Xin )
astfel nct X i1 < X i2 < < X in iar 1 < = ik < = n ; 1 < = k < = n .
d ) Pe primele poziii s apar elementele negative in aceeai ordine ca n irul iniial .
8. Fie E un numr natural cu n cifre memorate ntr-un vector cu n din domeniul 0..9. S se verifice
dac E este un numr divizibil cu :
a) 2 ; b) 5 ; c) 4 ; d) 3 ; e) 9 ; f) 7 ; g)11 ; h) 8 ; i) 25 ; j) 125 ;
k) 13 ; l) 27 ; m) 37 ; n) 6 ; o) 15.
9. S se afieze toate numerele de n cifre care adunate cu rsturnatul lor dau un ptrat perfect .
11. S se implementeze un algoritm care pentru dou numere ntregi cu n cifre memorate vectorial
s determine suma, produsul, ctul i restul mpririi primului numr la al doilea numr.
Rezultatele se vor obine sub forma vectorial .
________________________________________________________________________________
178
Structuri de date i algoritmi
_______________________________________________________________________________
O alt metod relativ simpl de accesare a unei tabele este metoda cutrii binare.
Organizarea datelor n aceast tabel se bazeaz pe ordonarea linear a cheilor (de exemplu, n
ordine alfabetic sau ordine numeric cresctoare). O metod potrivit pentru ordonarea datelor este
sortarea, despre care vom vorbi ntr-un alt capitol.
O cutare pentru o nregistrare cu o anumit valoare a cheii este asemntoare cu cutarea
unui nume ntr-o agend de telefoane. Este localizat cu aproximaie nregistrarea din mijlocul
tabelei, este comparat cheia nregistrrii din mijloc cu cheia nregistrrii cutate. Dac cheia
cutat este mai mare dect valoarea cheii din mijloc atunci procedura se repet n jumtatea de
interes a tabelei, pn cnd nregistrarea dorit este gsit sau intervalul de cutare este gol, ceea ce
semnific lipsa cheii cutate.
n Figura 4.1 avem un exemplu de cutare binar a cheii m aflat ntr-o tabel construit
prin inserarea cheilor a s e a r c h i n g e x a m p l e (Tre, [1984]). Intervalul de chei este
njumtit la fiecare pas, deci numai patru comparaii snt necesare n acest caz.
Operaia de inserare (metoda inseriei binare ) realizeaz n fiecare din cei N-1 pai ai si
nserarea celei de a i a nregistrri din tabloul iniial n irul deja sortat al precedentelor i -1
nregistrri .
Determinarea poziiei de nserare se face prin cutare binar, folosindu-se faptul c
nregistrrile precedente sunt deja sortate i reducndu-se astfel numrul mediu de comparaii
necesare de la i/2 la log 2 i .
Operaia de tergere este identic cu cea din cutarea secvenial, adic elementele din
tablou, aflate naintea elementului care va fi ters, vor rmne pe loc, poziiile lor nu se schimb
Elementele care se afl dup elementul care va fi ters, vor fi translatate cu o poziie.
________________________________________________________________________________
179
Structuri de date i algoritmi
_______________________________________________________________________________
LOW := 1
HIGH := N
CTTIMP LOW <= HIGH EXECUT
MIDDLE := [(LOW +HIGH ) / 2 ]
DAC X < K [MIDDLE]
ATUNCI HIGH := MIDDLE-1
ALTFEL DAC X > K [MIDDLE]
ATUNCI LOW := MIDDLE + 1
ALTFEL {Cutare cu succes }
@returneaz MIDDLE.
SFDAC
SFDAC
SFCT
@returneaz 0. {Cutare fr succes }
________________________________________________________________________________
180
Structuri de date i algoritmi
_______________________________________________________________________________
SFDAC
SF-CAUTARE_BINARA;
Timpul de cutare (execuie), T(n) depinde de numrul de comparaii efectuate, care depind
la rndul lor de poziia informaiei cutate X. n cel mai bun caz, informaia cutat este poziionat
n 1
n locaia (am notat cu [ ] funcia parte ntreag). n aceast situaie este necesar doar o
2
________________________________________________________________________________
181
Structuri de date i algoritmi
_______________________________________________________________________________
singur operaie de comparaie, deci T(n) = O(1). Cutarea binar nu folosete nici odat mai mult
de lg N +1 comparaii pentru cutarea cu succes, ct i pentru cutarea fr succes ([Aho, 1987]).
In procesul de cutare binar recursiv cheia cutat este gsit n maximum logN comparaii
care este un ctig deosebit faa de cele N/2 comparaii ale cutrii secveniale .
Pentru a determina timpul de cutare n cazul operaiei de cutare binar, vom considera c
toate datele sunt echiprobabile. Pentru a simplifica analiza vom presupune c dimensionalitatea
datelor este de forma n 2 k 1 . Atunci k log 2 n 1 .
Aceast ipotez nu distruge generalitatea argumentaiei, cci putem oricnd completa o
structur de date cu elemente care nu sunt cutabile, ca s o aducem la forma 2k 1. Oricum, timpul
de execuie al structurii de date originale va fi mai mic sau egal dect a structurii de date aduse la
forma n 2 k 1 .
S notm cu Si, numrul de elemente pentru care algoritmul de cutare binar efectueaz un
numr de i operaii (comparaii). Avem:
S 1 1 2 0 ; S 2 2 21 ; S 3 4 2 2 ; , S i 2 i 1 , i k
1 k
i i 2 i 1 i 2 i 2 i 1 i 2 i i 1 2 i
k 1
k k
Si 1 k 1 k
T n pi d i
i 1 i 1 n n i 1 n i 1 n i 1 i 0
1 1
i 2 i 2 2 i k 2 k 2 k 1 k 1 2 k 1 k k 1
k k 1 k 1
i i 1 k
n i 1 i 1 i 0 n n n
log 2 n 1 1
log 2 n 1 1 1 log 2 n 1 1 log 2 n
n n
Putem considera c avem: T n O log 2 n , att pentru cazul general ct i pentru cel mai
nefarorabil caz.
________________________________________________________________________________
182
Structuri de date i algoritmi
_______________________________________________________________________________
Exemplul 4.3. Problema cutrii elementelor comune a dou iruri de numere [Tud, 1993].
Aceast problem construiete vectorul elementelor comune a doi vectori (a, b). Se va
parcurge secvenial vectorul a, i fiecare element care este gsit i n vectorul b va fi memorat ntr-
un vector nou c construit de ctre subprogram .
Acest program funcioneaz att pentru vectori ordonai cresctor, ct i pentru vectori
ordonai descresctor.
Program elemente_comune ;
const
max_elem = 10 ;
type
cazuri = ( constant , cresc , desc ,neord ) ;
val_indice = 1 .. max_elem ;
vector = array [val_indice ] of integer ;
var
a , b , c : vector ;
na , nb , ic , indice : val_indice ;
tip : cazuri ;
Procedure citete vector ( var x : vector ; var numr : val_indice ; car : char ) ;
var
i : integer ;
begin
i := 0 ;
repeat
i := i + 1 ;
write ( , car , [ , I :2 , ] = ) ; read (x [ i ]) ;
if ( i mod 5 ) = 0
then writeln ;
until ( x[ i ] < 0 ) or ( i > = max_elem ) ;
if x [ i ] < 0
then numr : = i 1
else
numr : = i ;
writeln ;
end
end ;
________________________________________________________________________________
183
Structuri de date i algoritmi
_______________________________________________________________________________
begin
for i : = 1 to numr do
begin
write ( x [ , I : 2 , ] = , x [ I ] ) ;
If ( i mod 5 ) = 0
then writeln ;
end
end ;
________________________________________________________________________________
184
Structuri de date i algoritmi
_______________________________________________________________________________
begin
numr := 0 ;
for indice := 1 to nx do
case tip of
constant : if x [ indice ] = y [ 1 ]
then memoreaz ;
desc , cresc : if cutare _bin ( y , ny , x [ indice ] )
then memoreaz ;
________________________________________________________________________________
185
Structuri de date i algoritmi
_______________________________________________________________________________
{ program principal }
BEGIN
citete vector ( a , na , a );
citete vector ( b , nb , b );
tip := tip_ord ( a , na ) ;
if tip = neord ;
then
begin
tip := tip_ord ( b , nb );
construiete ( a , b , na , nb , ic )
end
else
construiete ( b , a , nb , na , ic );
writeln ;
if ic <> 0
then
begin
writeln ( Elementele comune sunt : ) ;
writeln ;
afieaza ( c , ic );
end
else
writeln ( Nu exist elemente comune );
END.
Program cutare_binar ;
var
a : array [ 1.. 1000 ] of real ;
x : real ;
i , n , margs , margd , jum : integer ;
este : boolean ;
BEGIN
write ( ' Nr . elemente = ') ;
readln ( n) ;
write ( ' Introducei elementele cu spaii sau enter : ') ;
________________________________________________________________________________
186
Structuri de date i algoritmi
_______________________________________________________________________________
V.1.2.5.Probleme propuse
1. Dac o operaie de cutare ce folosete algoritmul de cutare secvenial necesit exact 638 de
operaii, ct va dura operaia de cutare dac folosete algoritmul de cutare binar?
2. Pentru ce valori al lui N algoritmul de cutare binar este n medie mai lent dect algoritmul de
cutare secvenial, presupunnd o cutare cu succes?
4. ListaOrdonata este un tablou de tip ntreg cu 10 poziii. Cum ar arta tabloul ListaOrdinara n
cazul n care ar conine urmtoare valori, citite dintr-un fiier: 14, 27, 95, 12, 26, 5, 33, 15, 9, 99 i
elementele ar fi sortate n ordine cresctoare?
________________________________________________________________________________
187
Structuri de date i algoritmi
_______________________________________________________________________________
Intr-o structur de date de tip arbore de cutare, informaiile, sunt structurate pe nivele, pe
primul nivel, numit nivel 0, exist un singur element numit rdcin, de care sunt legate mai multe
elemente numite fii care formeaz nivelul 1; de acestea sunt legate elementele de pe nivelul 2,
.a.m.d. (vezi figura V.1).
Un arbore este compus din elementele numite noduri sau vrfuri i legturile dintre acestea.
Dup cum am vzut, cea mai des utilizat form de organizare a unui arbore binar este urmtoarea:
Cheia nodului fiu stnga < Cheia nodului fiu stnga < Cheia nodului fiu stnga (5.1)
Utiliznd formula de mai sus se obin arbori binari speciali, utilizai pentru organizarea i
cutarea datelor, numii arbori binari de cutare ABC.
Un nod situat pe un anumit nivel este nod tat pentru nodurile legate de el, situate pe nivelul
urmtor, acestea reprezentnd fii si. Arborii, ca structuri de date dinamice, au foarte multe aplicaii
n informatic. Structurile arborescente sunt foarte des utilizate pentru memorarea i regsirea
rapid a unor informaii. Informaiile sunt organizate dup un cmp numit cheie, ales de
programator, care servete la identificarea lor datelor stocate n structura arborescent. De exemplu,
dac datele sunt datele relative la studenii unei faculti, atunci cheia poate fi aleas ca fiind
numele i prenumele studentului. Cheile trebuie alese n aa fel nct s nu apar chei duble. n
exemplul nostru relativ la studenii unei faculti poate c ar fi mai bine s evitm posibilitatea
existenei unor chei duble, acelai nume i prenume, prin introducerea iniialei tatlui, evitnd astfel
cheile duble.
Un arbore binar de cutare este un arbore ale crui noduri cuprind o singur cheie de
identificare, nodurile cu chei mai mici dect o valoare X a cheii asociate unui anumit nod se gsesc
n subarborele stng al acestui nod, iar nodurile ale cror chei au valori mai mari dect X se gsesc
n subarborele su drept.
Cutarea unei informaii identificate printr-o valoare X a cheii ncepe de la rdcin i se
termin n cel mai ru caz la unul din nodurile terminale, cutarea presupunnd testarea a cel mult
attea noduri cte nivele are arborele binar de cutare. Dispunerea nodurilor arborelui pe nivele face
ca numrul operaiilor de testare la cutare s fie mult mai mic dect n cazul listelor ordonate.
________________________________________________________________________________
188
Structuri de date i algoritmi
_______________________________________________________________________________
________________________________________________________________________________
189
Structuri de date i algoritmi
_______________________________________________________________________________
Type
Adresa = ^Nod
Nod = RECORD
Fiu_st : Adresa;
Cheia : tipcheia;
Alte_info : tipinfo;
Fiu_dr : Adresa;
end
DATE root;
REZULTATE root;
________________________________________________________________________________
190
Structuri de date i algoritmi
_______________________________________________________________________________
Vom folosi subalgoritmul numit Creare_nod care va aloca dinamic spaiul de memorie
necesar noului nod de inserat i va completa cmpurile nodului ABC.
OBS. 5.x: Vom folosi n cele ce urmeaz o referin de tip Pascal pentru algoritmul n Pseudocod, i
anume:
adresa^.cmp
unde adresa reprezint variabila de tip adres a nodului, iar cmp reprezint numele cmpului
nodului. Descrierea algoritmului n Pseudocod este:
ALGORITMUL INSERARE ESTE: { Se insereaz un nod nou ca nod terminal, prima dat
se caut nodul tat }
CITETE cheia_nou, info_nou;
DAC ROOT = NIL ATUNCI { primul nod inserat }
CHEAM Creare_nod (cheia_nou, info_nou); { se aloc spaiu pentru noul nod de }
ROOT = NOU; { inserat la adresa NOU i se completeaz cmpurile }
EXIT;
SFDAC
tmp := ROOT;
CTTIMP tmp <> NIL EXECUT
Tata := tmp;
DAC cheia_nou < tmp^.cheia
ATUNCI tmp := tmp^.fiu_st;
ALTFEL DAC cheia_nou > tmp^.cheia
ATUNCI tmp := tmp^.fiu_dr;
ALTFEL
TIPRETE (EROARE CHEIE DUBL);
EXIT;
SFDAC
SFDAC
SFCT
CHEAM Creare_nod (cheia_nou, info_nou);
________________________________________________________________________________
191
Structuri de date i algoritmi
_______________________________________________________________________________
Exist mai multe situaii posibile, n funcie de numrul de fii ai nodului de ters [Tre, 1984]:
________________________________________________________________________________
192
Structuri de date i algoritmi
_______________________________________________________________________________
Cazul 1: nodul de ters este un nod terminal, deci fr fii. Operaia de tergere necesit
eliminarea legturii nod_tat i nod_de_ters i eliberarea spaiului ocupat de nodul de ters.
Exemplu: nodurile cu cheia 1, 4, 7, 10 din ABC figura 5.1.
Cazul 2: nodul de ters este un singur fiu. Operaia de tergere necesit realizarea legturii
nod_tat i nod_de_fiu (stnga sau dreapta) i eliberarea spaiului ocupat de nodul de ters.
Exemplu: nodurile cu cheia 3, 6, 9 din ABC figura 5.1.
Cazul 3: nodul de ters este doi fii. n aceast situaie nodul de ters trebuie nlocuit i abia dup
aceea poate fi eliminat. Nodul nlocuitor poate fi nodul cu cheia cea mai mare din punct de vedere
lexicografic din subarborele stng al nodului de ters sau nodul cu cheia cea mai mic din
subarborele drept al nodului de ters.
Exemplu: nodurile cu cheia 2, 5, 8 din ABC figura 5.1. Nodul nlocuitor al nodului cu cheia 2 este
nodul cu cheia 1 din subarborele stng sau nodul cu cheia 3 din subarborele su drept. Nodul
nlocuitor al nodului cu cheia 5 este nodul cu cheia 4 din subarborele stng sau nodul cu cheia 6 din
subarborele su drept. Nodul nlocuitor al nodului cu cheia 8 este nodul cu cheia 7 din subarborele
stng sau nodul cu cheia 9 din subarborele su drept.
Obs. 5.x: Pentru a gsi nodul nlocuitor al unui nod de ters n Cazul 3, acesta poate fi gsit astfel:
Dac nodul nlocuitor este nodul cu cheia cea mai mare din punct de vedere lexicografic din
subarborele stng al nodului de ters atunci se navigheaz de la nodul de ters un pas la stnga i
orici pai la dreapta, pn ajungem la o legtur nul. Dac nodul nlocuitor este nodul cu cheia
cea mai mic din punct de vedere lexicografic din subarborele drept al nodului de ters atunci se
navigheaz de la nodul de ters un pas la dreapta i orici pai la stnga, pn ajungem la o legtur
nul.
Descrierea general a algoritmului de tergere, n Pseudocod este:
________________________________________________________________________________
193
Structuri de date i algoritmi
_______________________________________________________________________________
EXIT;
SFDAC
DAC tmp^.fiu_st = NIL i tmp^.fiu_dr = NIL ATUNCI
CHEAM Cazul_1 (ROOT, tata, tmp); { Cazul 1 }
EXIT;
SFDAC
DAC tmp^.fiu_st = NIL xor tmp^.fiu_dr = NIL ATUNCI
CHEAM Cazul_2 (ROOT, tata, tmp); { Cazul 2 }
EXIT;
SFDAC
CHEAM Cazul_3 (ROOT, tata, tmp); { Cazul 3 }
SFALGORITM
194
Structuri de date i algoritmi
_______________________________________________________________________________
tata := tmp;
CTTIMP tmp^.fiu_dr <> NIL EXECUT { Orici pai la dreapta}
tata := tmp;
tmp := tmp^.fiu_dr; { Adresa tatlui nodului nlocuitor este n variabila tata}
SFCT { Adresa nodului nlocuitor este n variabila tmp}
adr^.cheia := tmp^.cheia; { nlocuim nodul de ters cu nodul nlocuitor}
adr^.info := tmp^.info; { nlocuim nodul de ters cu nodul nlocuitor}
tata^.fiu_dr := tmp^.fiu_st; { Eliminm legtura tata - nodul nlocuitor}
@Eliberare spaiu (tmp); { Eliberarea spaiului nod nlocuitor de la adresa tmp }
SF-Cazul_3
V.2.1.4. Probleme rezolvate
Exemplul 5.x: Problema arborilor asociai expresiilor aritmetice. Fiind date n expresii aritmetice
sintactic corecte care cuprind paranteze, operanzi notai cu literele mici din alfabet i operatori
binari sau unari din mulimea {+, -, *, / }, s se construiasc i s se afieze n postordine arborele
binar asociat fiecrei expresii [Dal, 1988].
Arborele binar asociat expresiei aritmetice - (a + b)*c - d este prezentat n figura urmtoare:
Se observ c rdcina cuprinde simbolul ultimei operaii, subarborele stng, iar nodul din
dreapta corespunde operandului drept; aceeai regul se aplic subarborilor. Operatorul "-" unar din
expresie s-a transformat n arborele binar n "&" pentru a-l distinge de cel binar; nodul asociat
operatorului are numai subarbore drept ( operaia este unar ).
Existena operatorilor "+" sau "-" unari modific numai diagrama de sintax a expresiei
aritmetice ( vezi figura ), celelalte rmnnd neschimbate.
________________________________________________________________________________
195
Structuri de date i algoritmi
_______________________________________________________________________________
Program arbori_asociati_expresiilor_aritmetice ;
type
reper =^nod ;
nod = record
v : char ;
stg, dr : reper ;
end ;
var
rad : reper ;
x : pointer ;
i, n : byte ;
car : char ;
procedure citire ;
begin
if not eoln then read(car)
end ;
________________________________________________________________________________
196
Structuri de date i algoritmi
_______________________________________________________________________________
begin
citire ;
expresie (p) ; { aici car =) }
end ;
else
begin
new(p) ;
p ^.v := car ;
p ^.stg := NIL ;
p ^.dr := NIL ;
end ;
citire ;
end ;
procedure termen ;
var q : reper ;
begin
factor ( p ) ;
while car in [ '*', '/' ] do
begin
new ( q ) ;
q ^.v := car ;
q ^.stg := p ;
citire ; { operandul 2 ncepe dup car }
factor (q ^. dr) ; { creeaz si leag n dr. nodului q ^ }
p := q ; { subarb. asociat operandului 2 al lui car }
end ;
end ;
procedure expresie ;
var q : reper ;
begin
if car in [ '+', '-' ] then { expresia ncepe cu + sau - }
if car = '-' then
begin { car = - unar }
new ( p ) ;
p ^.v := '$' ; { $= - unar }
p ^.stg := NIL ;
citire ;
termen(p ^.dr) ;
end
else
begin { car =+ unar }
citire ;
termen ( p );
end
________________________________________________________________________________
197
Structuri de date i algoritmi
_______________________________________________________________________________
else termen ( p ) ;
while car in [ '+', '-' ] do
begin
new ( q ) ;
q ^.v := car ;
q ^.stg := p ;
citire ;
termen ( q ^.dr) ;
p := q;
end
end ;
(a+b)*(c-d)
abc+cd-*
-a+b
a$b+
Primul tip de arbore balansat este Arborele Binar de Cutare Balansat n nlime -
ABCBI. Intr-un astfel de arbore ncercm meninerea tuturor nodurilor frunz la aceeai distant
fa de rdcin .
________________________________________________________________________________
198
Structuri de date i algoritmi
_______________________________________________________________________________
In Figura V.2. este prezentat un arbore binar de cutare balansat n nlime, iar n Figura
V.3. este prezentat un arbore binar debalansat [Tre, 1984].
Definiia V.2. Nod greu dreapta (R) : Un nod al unui ABCBI se numete nod greu dreapta, dac
nlimea subarborelui su drept este mai mare cu 1 dect nlimea subarborelui su stng.
Definiia V.3. Nod balansat (B) : Un nod al unui ABCBI se numete nod balansat, dac nlimea
subarborelui su stng este egal cu nlimea subarborelui su drept.
Definiia V.4. Nod critic (C) : Un nod al unui ABCBI se numete nod critic, dac nu este nod greu
dreapta, nod greu stnga sau nod balansat.
ntr-un ABCBI fiecare nod trebuie se afle in una din aceste trei stri, adic s fie nod greu
dreapta, nod greu stnga sau nod balansat.
Definiia V.5. Un arbore binar de cutare se numete arbore binar de cutare balansat n nlime
ABCBI, dac are doar noduri greu stnga, noduri greu dreapta sau noduri balansate.
________________________________________________________________________________
199
Structuri de date i algoritmi
_______________________________________________________________________________
Dac exist un nod care nu satisface nici una din aceste trei stri, atunci arborele se numete
arbore binar debalansat.
Definiia V.6. Un arbore binar de cutare se numete arbore binar de cutare debalansat dac
conine cel puin un nod critic.
200
Structuri de date i algoritmi
_______________________________________________________________________________
e. traversarea:
a. Operaia de inserare. In cazul operaiei de inserare al unui nod, presupunem c inserarea se face
la nivelul unui nod terminal, dup regula general de inserare de la arborii binari de cutare. Numai
la acele noduri se schimb indicatorul de balansare n cazul unui astfel de nserri, care se afl pe un
drum cuprins ntre rdcin arborelui i noul nod terminal inserat, numit drum de inserare.
Posibilele schimbri pentru un nod, aflat pe drumul de inserare sunt urmtoarele [Tre, 1984]:
Cazul 1: Nodul era nod greu dreapta sau nod greu stnga i a devenit balansat.
Cazul 2: Nodul era balansat i a devenit nod greu dreapta sau nod greu stnga.
Cazul 3: Nodul era un nod greu, iar noul nod este nserat n subarborele su greu, crend un
subarbore debalansat. Un astfel de nod se numete nod critic.
________________________________________________________________________________
201
Structuri de date i algoritmi
_______________________________________________________________________________
Operaia de inserare poate duce la crearea unor noduri critice, deci la debalansarea arborelui.
Pentru a putea pstra caracteristica de ABCBI, este necesar efectuarea unei operaii specifice,
numit rebalansare a arborelui, care s duc la eliminarea nodurilor critice i la transformarea lor n
noduri greu dreapta, greu stnga sau balansat.
Sunt dou cazuri de rebalansare, care se divid fiecare n dou subcazuri, corespunztoare
direciei grele stnga sau dreapta care a dus la apariia nodului critic [Tre, 1884].
Cazul 1: Rebalansare prin rotaie simpl. Acest caz apare cnd operaia de inserare s-a fcut pe
direcia grea a nodului care a devenit critic. Cele dou sub cazuri sunt:
Cazul 1.a.: Rebalansare prin rotaie simpl la dreapta. Acest caz apare cnd operaia de inserare s-
Cazul 1.b.: Rebalansare prin rotaie simpl la stnga. Acest caz apare cnd operaia de inserare
s-a fcut pe direcia grea dreapta a nodului care a devenit critic.
O reprezentare a cazului 1.a, este n Figura V.8., unde T1, T2 i T3 reprezint subarbori, iar
NEW reprezint noul nod de inserat. Expresia din partea de jos a dreptunghiurilor reprezint
nlimea subarborilor, nainte i dup inserare.
De exemplu, n Figura V.8. (a.1) presupunem c n urma unei operaii de inserare nodul X,
din nod greu stnga, a devenit critic. Atunci arborele binar devine debalansat. Problema se rezolv
dac rotim la dreapta arborele n jurul nodului nodul Y, Figura V.8. (a.2).
________________________________________________________________________________
202
Structuri de date i algoritmi
_______________________________________________________________________________
Figura V.8. Exemplu de soluionare a debalansrii arborelui binar, prin rotaie simpl la
dreapta n jurul nodului Y.
Figura V.9. Exemplu de soluionare a debalansrii arborelui binar, prin rotaie simpl la
stnga n jurul nodului Y.
De exemplu, n Figura V.8. (b.2) presupunem c n urma unei operaii de inserare nodul X,
din nod greu dreapta, a devenit critic. Atunci arborele binar devine debalansat. Problema se
rezolv dac rotim la stnga arborele n jurul nodului nodul Y, Figura V.8. (b.1).
Cazul 2: Rebalansare prin rotaie dubl. Acest caz apare cnd operaia de inserare s-a fcut pe
direcia opus direciei grele a nodului care a devenit critic. Cele dou subcazuri sunt:
Cazul 2.a.: Rebalansare prin rotaie dubl la dreapta. Acest caz apare cnd operaia de inserare s-
a fcut pe direcia opus direciei grele stng a nodului care a devenit critic.
Cazul 2.b.: Rebalansare prin rotaie dubl la stnga. Acest caz apare cnd operaia de inserare s-a
fcut pe direcia opus direciei grele dreapta a nodului care a devenit critic.
Cazul doi, care este reprezentat n Figura V.9 i Figura V.10., este asemntor cu primul
caz, cu excepia c nodul Y devine nod greu n direcia opus n care nodul X era nod greu. Este
clar c nodul Z trebuie balansat prioritar fa de inserare .
________________________________________________________________________________
203
Structuri de date i algoritmi
_______________________________________________________________________________
Figura V.10. Exemplu de soluionare a debalansrii arborelui binar, prin rotaie dubl la
stnga n jurul nodului Z.
________________________________________________________________________________
204
Structuri de date i algoritmi
_______________________________________________________________________________
Figura V.11. Exemplu de soluionare a debalansrii arborelui binar, prin rotaie dubl la
dreapta n jurul nodului Z.
Specificarea problemei de inserare, avnd ca date de intrare ROOT, cheia_nou, info_nou,
este urmtoarea:
________________________________________________________________________________
205
Structuri de date i algoritmi
_______________________________________________________________________________
________________________________________________________________________________
206
Structuri de date i algoritmi
_______________________________________________________________________________
else
if curent^.key > cheia then begin
tata := curent ;
curent := curent^.lptr ;
end
else begin
writeln ( ' Cheie dubl !' ) ;
readln ;
exit ;
end ;
new ( nou ) ;
nou^.key := cheia ;
nou^.lptr := nil ;
nou^.rptr := nil ;
if cap = nil then begin
cap := nou ;
exit ;
end;
if cheia < tata^.key then tata^.lptr := nou
else tata^.rptr := nou ;
balansinalt ;
end;
207
Structuri de date i algoritmi
_______________________________________________________________________________
else begin
tata^.rptr := nil ;
dispose ( temp ) ;
end
else if ( temp^.lptr = nil ) xor ( temp^.rptr = nil ) then
{ nodul de ters are un singur fiu }
begin
if temp^.lptr = nil then fiu := temp^.rptr
else fiu := temp^.lptr ;
if temp^.key < tata^.key then tata^.lptr := fiu
else tata^.rptr := fiu ;
dispose ( temp ) ;
end
else begin
predec := temp^.lptr ; tatap := predec ;
while predec^.rptr <> nil do
begin
tatap := predec ; predec := predec^.rptr ;
end ;
temp^.key := predec^.key ;
if predec^.lptr <> nil then begin
tatap^.rptr := predec^.lptr ;
dispose ( predec ) ;
end ;
if predec = tatap then begin
temp^.lptr := nil ;
dispose ( predec ) ;
end ;
end ;
end ;
208
Structuri de date i algoritmi
_______________________________________________________________________________
Procedure meniu ;
begin
repeat
clrscr ;
writeln ( ' Optiuni : C-Creare ');
writeln ( ' I-Inserare ');
writeln ( ' S-tergere ');
writeln ( ' T-Traversare-N-Inordine ' ) ;
writeln ( ' T-Traversare-P-Preordine ' ) ;
writeln ( ' T-Traversare-O-Postordine ' ) ;
writeln ( ' ESC-Ieire ');
c := readkey ;
case upcase ( c ) of
' C ' : begin
writeln ; writeln ( '* CREARE *' : 15 ) ; writeln ;
write ( 'Creez rdcina...' ) ;
creare ( root ) ; writeln ( ' OK! ' ) ;
readkey ;
________________________________________________________________________________
209
Structuri de date i algoritmi
_______________________________________________________________________________
end ;
' I ' : begin
writeln ; writeln( ' * INSERARE * ' : 15 ) ; writeln ; writeln ;
write ( ' Cheia : ' ) ; readln( s ) ; writeln ;
insere ( root , s ) ;
end ;
' S ' : begin
writeln ; writeln (' *TERGERE * ' : 15 ) ; writeln ;
write ( ' Cheia elementului pt. sters: ' ) ;
readln ( s ) ; sterge ( root , s ) ;
end ;
' T ' : begin
writeln ; writeln ( ' * TRAVERSARE * ' : 15 ) ; writeln ;
write ( ' Optiunea: ' ) ; readln(c) ;
if root^.key = 0 then
begin
writeln ; writeln ( ' Arbore vid ! ' : 15 ) ;
c := ' ' ;
end ; writeln ;
case upcase ( c ) of
' N ' : begin
write ( ' Inordine: ' ) ;
inordine ( root ) ;
readkey ;
end ;
' P ' : begin
write ( ' Preordine: ' ) ;
preordine ( root ) ;
readkey ;
end ;
' O ' : begin
write ( ' Postordine: ' ) ;
postordine ( root ) ;
readkey ;
end ;
else writeln ( ' Ai apsat o tast gresit ! ' ) ;
end ;
end ;
end ;
until c = # 27 ;
end ;
BEGIN
meniu ;
END.
________________________________________________________________________________
210
Structuri de date i algoritmi
_______________________________________________________________________________
________________________________________________________________________________
211
Structuri de date i algoritmi
_______________________________________________________________________________
Obs.: In orice arbore (subarbore) nodul rdcin este cel mai greu nod.
Arborele prezentat n figura de mai jos, este o structur de date de tip ABCBG. Se observ
c n primul rnd avem un ABC deoarece, lexicografic avem respectat regula de organizare a
arborilor binari de cutare. De asemenea, se observ c nodurile cele mai grele se gsesc la
nceputul drumului de cutare, adic ct mai aproape de nodul rdcin [Tre, 1884]..
Regula de plasare al unui nod n arborele binar de cutare balansat n greutate poate fi
exprimat n mod recursiv dup urmtoarea regul [Aho, 1987] :
1. Nodul rdcin al oricrui arbore (subarbore) este nodul cu cea mai mare greutate din
mulimea de noduri care constituie arborele (subarborele);
2. Subarborele stng al oricrui arbore (subarborelui) este compus din noduri a cror
valoare lexical este mai mic dect nodul rdcin;
3. Subarborele drept al oricrui arbore (subarborelui este compus din noduri a cror valoare
lexical este mai mare dect nodul rdcin.
n cazul arborelui binar de cutare balansat n greutate, la fiecare operaie de inserare sau la
o orice operaie de accesare a unui anumit nod, greutatea nodului este incrementat cu 1. Dac se
insereaz un nod nou n arbore, acesta va fi poziionat conform cu regulile generale de inserare de la
arborii binari de cutare, ca i nod terminal, greutatea nodului fiind iniializat cu 1.
S considerm n continuare acelai arbore binar de cutare, dar care s nu mai fie balansat
n greutate.
________________________________________________________________________________
212
Structuri de date i algoritmi
_______________________________________________________________________________
unde:
Fiu_st : reprezint adresa fiului stnga;
Cheia: reprezint cmpul ales dup care este ordonat ABCBG;
________________________________________________________________________________
213
Structuri de date i algoritmi
_______________________________________________________________________________
c. Operaia de cutare.
________________________________________________________________________________
214
Structuri de date i algoritmi
_______________________________________________________________________________
Obs.V.2: Vom presupunem existenta unei stive care este folosit pentru a memora drumul de
cutare, de la nodul rdcin pn la nodul cutat. Aceast stiv va fi necesar pentru operaia de
tergere.
________________________________________________________________________________
215
Structuri de date i algoritmi
_______________________________________________________________________________
216
Structuri de date i algoritmi
_______________________________________________________________________________
begin
inc ( temp^.weight ) ;
writeln ( ' Cutare cu succes Informaia exist ' ) ;
cautare := temp ;
rebalansare ( temp , tata ) ; { rebalanseaz arborele dac este necesar }
exit ;
end
else
begin
cautare := nil ;
writeln ( ' Cutare cu insucces Informaia nu exist ' ) ;
end ;
end ;
d. Operaia de tergere.
n cazul operaiei de tergere al unui nod, avem 4 cazuri care trebuie examinate [Tre, 1884]..
Cazul 1. Nodul de ters este un nod frunz. In acest caz, tergerea este simpl, tergem legtura care
leag nodul frunz de nodul printe.
Cazul 2. Nodul este un nod neterminal, care nu are subarbore drept, i nodul de ters este un nod fiu
stnga. n acest caz fiul stng al nodului printe va deveni egal cu fiul stng al nodului marcat
pentru tergere. Aceeai rezolvare pentru cazul simetric.
Cazul 3. Nodul este un nod neterminal, care nu are subarbore stng, i nodul de ters este un nod
fiu stnga. n acest caz fiul stng al nodului printe va deveni egal cu fiul drept al nodului marcat
pentru tergere. Aceeai rezolvare pentru cazul simetric.
Cazul 4. Nodul este nod neterminal, cu ambii subarbori nenuli. In acest caz tergerea direct a
nodului ar duce la debalansarea arborelui. Pentru a nu debalansa arborele, se va nlocui nodul de
ters cu un nod urma, i anume cu acela care are cea mai mare greutate. n urma aplicrii acestei
nlocuiri, ne vom regsi ntr-una din regulile exprimate prin Cazurile 1,2,3 sau 4. Repetm regula
1,2, 3 sau 4, pn cnd se poate terge nodul dorit
________________________________________________________________________________
217
Structuri de date i algoritmi
_______________________________________________________________________________
program ABCBG;
const max=100;
type adresa = ^nod;
nod = record
lptr : adresa ;
key : char ;
info : string[30] ;
rptr : adresa ;
weight : word ;
end ;
str = string[30] ;
stiva = array[0..max] of adresa ;
top = 0..max ;
var
tata , temp , copil , root , rad : adresa ;
ch : char ;
student : nod ;
i , n : integer ;
st : stiva ;
ind : top ;
________________________________________________________________________________
218
Structuri de date i algoritmi
_______________________________________________________________________________
219
Structuri de date i algoritmi
_______________________________________________________________________________
new(nou) ;
nou^.key := cheia ;
nou^.weight := 0 ;
nou^.lptr := nil ;
nou^.rptr := nil ;
rad := nou ;
end
else begin { inserare n cazul cnd arborele nu este vid }
curent := rad ; tata := curent ;
while curent <> nil do
if cheia < curent^.key then { inserarea fiului stng al nodului curent }
begin
tata := curent ;
curent := curent^.lptr ;
end
else if cheia > curent^.key then { inserarea fiului drept al nodului curent }
begin
tata := curent ;
curent := curent^.rptr ;
end
else begin
writeln ( 'cheie dubl:eroare') ;
exit ;
end ;
new (nou) ; {inserarea propriuzis i actualizarea cmpurilor }
nou^.key := cheia ;
nou^.weight := 0 ;
nou^.lptr := nil ;
nou^.rptr := nil ;
if tata^.key > cheia then tata^.lptr := nou
else tata^.rptr := nou ;
end ;
end ;
220
Structuri de date i algoritmi
_______________________________________________________________________________
end
else
begin
tata^.rptr := temp^.lptr ;
temp^.lptr := tata ;
root := temp ;
exit ;
end
else
t := pop (st,ind) ;
bunic := pop (st,ind) ;
if tata^.key < bunic^.key then
if temp^.key<tata^.key then
begin
bunic^.lptr := temp ;
tata^.lptr := temp^.rptr ;
temp^.rptr := tata ;
end
else
begin
bunic^.lptr:=temp;
tata^.rptr:=temp^.lptr;
temp^.lptr:=tata;
end
else
if temp^.key<tata^.key then
begin
bunic^.rptr:=temp;
tata^.lptr:=temp^.rptr;
temp^.rptr:=tata;
end
else
begin
bunic^.rptr:=temp;
tata^.rptr:=temp^.lptr;
temp^.lptr:=tata;
end;
push (st,ind,bunic) ;
tata:=bunic ;
rebalansare (temp,tata) ;
end ;
221
Structuri de date i algoritmi
_______________________________________________________________________________
begin
if cheiac<temp^.key then begin { se caut n subarborele stng }
tata:=temp;
push(st,ind,tata);
temp:=temp^.lptr;
end
else begin { se caut in subarborele drept }
tata:=temp;
push(st,ind,tata);
temp:=temp^.rptr;
end;
end;
if temp^.key=cheiac then begin inc(temp^.weight); { cheia este gsit }
writeln('Exista');
cautare:=temp;
rebalansare(temp,tata);
exit;
end
else
begin
cautare:=nil;
writeln('Nu exist');
end;
end;
Procedure sterg;
var fiu , predec , tatap : adresa ;
begin
if (temp^.lptr=nil) and (temp^.rptr=nil) then {tergerea unui nod terminalCazul1}
if temp^.key<tata^.key then begin
tata^.lptr:=nil;
dispose(temp);
end
else begin
tata^.rptr:=nil;
dispose(temp);
end
else
if (temp^.lptr = nil) XOR (temp^.rptr = nil) then { tergerea unui nod cu un } begin
{ singur fiu Cazul 2, 3 }
if temp^.lptr<>nil then fiu:=temp^.lptr
else fiu:=temp^.rptr;
if temp^.key<tata^.key then begin
tata^.lptr:=fiu;
dispose(temp);
end
________________________________________________________________________________
222
Structuri de date i algoritmi
_______________________________________________________________________________
else begin
tata^.rptr:=fiu;
dispose(temp);
end;
end
else begin {tergerea unui nod cu doi fii Cazul 4}
predec:=temp;
tatap:=predec;
predec:=temp^.lptr;
while predec^.rptr<>nil do begin
tatap:=predec;
predec:=predec^.rptr;
end;
temp^.key:=predec^.key;
temp^.info:=predec^.info;
if predec^.lptr<>nil then tatap^.lptr:=predec^.lptr
else tatap^.lptr:=nil;
dispose(predec);
end;
end;
________________________________________________________________________________
223
Structuri de date i algoritmi
_______________________________________________________________________________
begin
menu;
creare(root);
repeat
ch := readkey;
case ch of
'1':begin
writeln;
write('introducei cheia:');
readln(student.key);
inserare(root,student.key);
end;
'2':begin
writeln;
write('introducei cheia cutat:');
readln(student.key);
cautare(root,student.key);
end;
'3':begin
writeln('traversare preordine:');
preordine(root);
end;
'4':begin
writeln;
write('introducei cheia de sters:');
readln(student.key);
stergere(root,student.key);
end;
end;
until ch='5';
end.
Un alt tip de arbore de cutare este arborele de cutare 2-3 AC2-3. Un arbore 2-3 este
________________________________________________________________________________
224
Structuri de date i algoritmi
_______________________________________________________________________________
definit ca un arbore de cutare n care nodurile non-frunz (neterminale) au 2 sau 3 fii, i toate
nodurile frunz (terminale) au aceeai distan fa de nodul rdcin.
Observaie: Un arbore care are un singur nod (nod frunz) este considerat a fi tot AC2-3. Evident,
arborii de cutare 2-3 nu sunt arbori binari, dei algoritmul de cutare este pe undeva asemntor
algoritmului de cutare binar.
Figura V.xx. ne prezint un exemplu de arbore 2-3 avnd inserate 5 date, cu cheile de
cutare 1, 3, 6, 7, 11. Celelalte noduri non-frunz sunt noduri pentru cutare.
ntr-un AC2-3 numai nodurile frunz conin date propriu-zise, celelalte noduri (nodurile
non-frunz) sunt noduri auxiliare de cutare.
Un nod non-frunz va fi denumit nod auxiliar de cutare. Un astfel de nod auxiliar de
cutare va conine dou valori, corespunztoare limitei inferioare respectiv limitei superioare a
drumului de cutare [Aho, 1987].
Limita inferioar a unui nod auxiliar de cutare reprezint cea mai mare cheie de cutare din
subarborele stng. Limita superioar a unui nod auxiliar de cutare reprezint cea mai mare cheie de
cutare din subarborele mijlociu.
Observaie: Cnd un nod non-frunz (neterminal) are doar doi fii, atunci se consider c fiul lips
este fiul din dreapta.
n cazul operaiilor de cutare, cheia de cutare este comparat cu cele dou valori limit ale
nodurilor auxiliare de cutare:
Dac cheia de cutare este mai mic sau egal cu limita inferioar de cutare, atunci
cutarea se face pe legtura fiu_stnga.
Dac cheia de cutare este strict mai mare dect limita inferioar de cutare, dar mai mic
sau egal dect limita superioar de cutare, atunci cutarea se face pe legtura fiu_mijloc.
Altfel, dac cheia de cutare este mai mare dect limita superioar de cutare i dac exist
legtura fiu_dreapta atunci cutarea se face pe legtura fiu_dreapta, altfel cutarea se face
pe legtura fiu_mijloc .
________________________________________________________________________________
225
Structuri de date i algoritmi
_______________________________________________________________________________
Unde:
fiu_st : reprezint adresa fiului stnga;
a: limita inferioar a drumului de cutare;
b: limita superioar a drumului de cutare;
tip: tipul nodului, nod auxiliar de cutare (non-frunz) tip = 1, nod de date (frunz) tip = 1;
fiu_mij : reprezint adresa fiului din mijloc;
fiu_dr : reprezint adresa fiului dreapta;
Unde:
tip: tipul nodului, nod auxiliar de cutare (non-frunz) tip = 1, nod de date (frunz) tip = 1;
cheia: reprezint cmpul de date ales dup care este ordonat AC2-3;
Alte_info: alte informaii;
________________________________________________________________________________
226
Structuri de date i algoritmi
_______________________________________________________________________________
end
a. creare-iniializare;
b. inserare;
c. cutare;
d. tergere;
e. traversarea:
b. Operaia de inserare.
Exist patru cazuri de analizat pentru operaia de inserare [Tre, 1884].. Acestea sunt:
Cazul 1. Arborele este vid. n acest caz alocm spaiu pentru noul nod frunz de inserat i acesta va
deveni noul nod rdcin.
Exemplu: n figura V.xx a se insereaz nodul cu cheia 4.
Cazul 2. Arborele conine un singur nod (acesta coincide cu nodul rdcin). n acest caz se creeaz
un nou nod non-frunz care va deveni noul nod rdcin, vechiul nod rdcin i noul nod de
inserat vor deveni fii nodului auxiliar de cutare.
Exemplu: n figura V.xx b se insereaz nodul cu cheia 9 n AC2-3 din figura V.xx.a.
________________________________________________________________________________
227
Structuri de date i algoritmi
_______________________________________________________________________________
Celelalte dou cazuri apar n situaia n care AC2-3 conine mai mult de un nod. Regula n
aceast situaie este urmtoarea: prima dat se determin locul unde ar urma s fie inserat noul nod,
dup care este determinat nodul tat, avnd grij ca s memorm drumul de cutare.
Cazul 3. Nodul tat are exact doi fii. Inserm noul nod la n poziia determinat de comparaia
cheilor de cutare.
Dac valoarea cheii de inserat este mai mic dect valoarea cheii nodului fiu stnga, atunci noul nod
de inserat va deveni fiul stng al nodului tat; dac valoarea cheii nodului de inserat este mai mare
dect cheia nodului fiu mijloc, atunci noul nod de inserat va deveni nodul fiu dreapta al nodului
tat; altfel noul nod de inserat va deveni nodul fiu mijloc al nodului tat. Aceast nserare este
prezentat n Figura III.11. .
Exemplu: n figura V.xx b se insereaz nodul cu cheia 9 n AC2-3 din figura V.xx.a.
Cazul 4. Nodul tat are trei fii. In acest caz, noul nod de inserat ar deveni al patrulea fiu al nodului
tat. Vom crea un nou nod non-frunz, nod frate cu nodul tat. Poziia nodului nod frate este
determinat de poziia i dispunerea nodurilor fiu. Cele patru noduri fii vor fi separate astfel: cei doi
frai din stnga i cei doi frai din dreapta vor fi ataai nodului tat iniial i nodului unchi nou
creat.
Exemplu: n figura V.xx se insereaz nodul cu cheia 9 n AC2-3 din figura V.xx.a.
________________________________________________________________________________
228
Structuri de date i algoritmi
_______________________________________________________________________________
Figura V.xx. Cazul 3 de inserare. n AC2-3 din stnga se insereaz un nou nod cu cheia 7.
Figura V.xx. Cazul 4 de inserare. n AC2-3 din stnga se insereaz un nou nod cu cheia 7.
________________________________________________________________________________
229
Structuri de date i algoritmi
_______________________________________________________________________________
ALTFEL
TIPRETE ( EROARE cheie dubl )
SFDAC
SFDAC
ROOT := tata ;
EXIT;
SFDAC
Tmp := ROOT ; { Cazul 3 sau 4 de inserare }
CTTIMP tmp^.tip <> 0 EXECUT { Cutm nodul tat}
DAC cheia_nou < tmp^.a ATUNCI
Push(stiva, top, tmp);
tmp := tmp^.fiu_st;
ALTFEL
Push(stiva, top, tmp);
tmp := tmp^.fiu_mijl;
SFCT { Adresa nodului tat este n vrful stivei}
tata := pop(stiva, top);
Dac tata^.fiu_dr := NIL
CHEAM Cazul_3_inserare (ROOT, tata, cheia_nou, info_nou);
________________________________________________________________________________
230
Structuri de date i algoritmi
_______________________________________________________________________________
ALTFEL
CHEAM Cazul_4_inserare (ROOT, tata, stiva, top, cheia_nou, info_nou);
SFALGORITM
Subalgoritmul Cazul_3_inserare este simplu de rezolvat. Se aloc spaiu pentru noul nod de
inserat, se compar cheia nodului de inserat cheia_nou cu limita inferioar tata^.a i limita
superioar tata^.b a nodului printe, inserndu-se n una din poziiile fiu_st, fiu_mij, fiu_dr. Se
actualizeaz corespunztor cmpurile nodului de inserat i cmpurile nodului tat.
c. Operaia de cutare.
________________________________________________________________________________
231
Structuri de date i algoritmi
_______________________________________________________________________________
d. Operaia de tergere.
Algoritmul de tergere presupune ntr-o prim faz gsirea nodului de ters i a nodului tat
al nodului de ters, dac acesta exist. Dac am gsit nodul de ters, atunci va trebui s analizm n
care din cazurile de mai jos ne situm:
Dac arborele conine un singur nod frunz, atunci algoritmul de tergere este trivial:
o Se actualizeaz adresa nodului rdcin care devine NIL;
o Se elibereaz spaiul de memorie ocupat de nodul de ters.
________________________________________________________________________________
232
Structuri de date i algoritmi
_______________________________________________________________________________
Dac nodul tat al nodului de ters are 3 fii, algoritmul de tergere este urmtorul:
o Se actualizeaz cmpurile nodului tat;
o Se elibereaz spaiul de memorie ocupat de nodul de ters.
Dac nodul tat al nodului de ters are 2 fii, algoritmul de tergere este urmtorul:
o Nodul frate rmas al nodului de ters se leag de un nod unchi;
o Dac nodul unchi avea 2 fii, n urma alipirii nodului va avea 3 fii;
o Dac nodul unchi avea 3 fii, n urma alipirii nodului va avea 4 fii, deci va trebui s
facem:
Vom crea un nou nod non-frunz, nod frate cu nodul tat. Poziia nodului nod
frate este determinat de poziia i dispunerea nodurilor fiu;
Cele patru noduri fii vor fi separate astfel: cei doi frai din stnga i cei doi
frai din dreapta vor fi ataai nodului tat iniial i nodului unchi nou creat.
e. Operaia de traversare.
Spre deosebire de arborii binari de cutare la arborii de cutare 2-3, datele propriu-zise se
gsesc pe acelai nivel sub forma de noduri terminale. De aceea traversarea AC2-3 este mai
special necesitnd un test suplimentar corespunztor deciziei dac avem de-a face cu un nod
terminal sau nu.
La fel ca la arborii de cutare, seciunea 4.5.2, cele trei modaliti de traversare difer prin,
momentul n care se viziteaz nodul rdcina i anume, n cazul:
preordine: se viziteaz nti rdcina, apoi subarborele stng, subarborele din mijloc i
dup aceea subarborele drept dac exist;
inordine: se viziteaz subarborele stng, se viziteaz rdcina, subarborele din mijloc i
subarborele drept dac exist, sau, se viziteaz subarborele stng, subarborele din mijloc,
se viziteaz rdcina i subarborele drept dac exist;
postordine: se viziteaz subarborele stng, subarborele din mijloc, subarborele drept
dac exist i rdcina.
233
Structuri de date i algoritmi
_______________________________________________________________________________
write ( def^.cheia : 3 ) ;
inordine_2_3 ( def^.fiu_mij ) ;
inordine_2_3 ( def^.fiu_dr ) ;
end ;
end ;
Dac un AC2-3 are nlimea h, atunci numrul de noduri frunz este cuprins ntre 2 h i 3h
[Sed, 1990]. Aceasta nseamn c nlimea unui AC2-3 cu n noduri este cel mult log2n, adic
algoritmul de cutare este direct proporional cu O(log2n).
________________________________________________________________________________
234
Structuri de date i algoritmi
_______________________________________________________________________________
Program Arbori_2_3;
Const max=100;
Type
str14 = string [14] ;
tip_nod = (terminal,neterminal);
adresa =^nod ;
nod = record
case tag : tip_nod of
neterminal : (lkey : integer ;
lptr : adresa ;
mkey : integer ;
mptr : adresa ;
rptr : adresa ; ) ;
terminal : (key : integer ) ;
end ;
top = 0..max;
stiva = array [1..max] of adresa;
VAR head,tata:adresa;
STACK:stiva;
DIR:array [1..max] of char;
topdir ,valoare , nr :integer;
ind : top ;
p,nou : adresa ;
succes : boolean ;
c :char ;
235
Structuri de date i algoritmi
_______________________________________________________________________________
begin
if ind = max then
full_stack := true
else
full_stack := false
end ;
Procedure push ( var st : stiva ; var ind : top ; var element : adresa ) ;
{ introducere n stiv }
begin
if not full_stack ( ind ) then
begin
st [ ind ] := element;
ind := ind+1;
end
else
begin
writeln ( ' stack owerflow ' ) ;
exit ;
end
end ;
Function pop ( var st : stiva ; var ind:top) : adresa ; { scoatere din stiv }
begin
if not empty_stack ( ind ) then
begin
ind := ind-1 ;
pop := st [ ind ] ;
end
else
writeln ( ' stack underflow ' ) ;
exit ;
end ;
236
Structuri de date i algoritmi
_______________________________________________________________________________
237
Structuri de date i algoritmi
_______________________________________________________________________________
p^.mkey := nr ;
p^.mptr := q ;
p^.rptr := temp2 ;
end
else p^.rptr := q ;
succes := true ;
end ;
end ;
Procedure Caut_tata ;
begin
p := head ;
Push (stack,ind,p) ;
while p^.lptr^.tag = neterminal do begin
if nr <= p^.lkey then begin
p := p^.lptr ;
Push (stack,ind,p) ;
end
else if nr <= p^.mkey then begin
p := p^.mptr ;
Push (stack,ind,p) ;
end
else if p^.rptr <> nil then begin
p := p^.rptr;
Push (stack,ind,p);
end
else begin
p := p^.mptr ;
Push (stack,ind,p);
end ;
end
end;
238
Structuri de date i algoritmi
_______________________________________________________________________________
begin
tata^.lkey := nr ;
tata^.lptr := nodnou ;
tata^.mkey := inform(temp1);
tata^.mptr := temp1;
tata^.rptr := temp2;
end
else if nr <= inform (temp2)
then begin
tata^.mkey := nr;
tata^.mptr := nodnou ;
tata^.rptr := temp2 ;
end
else begin
tata^.rptr := nodnou ;
end ;
end
else
begin
new (frate) ; frate^.tag:=neterminal;
if nr < inform (temp1)
then
begin
tata^.lkey := nr;
tata^.lptr := nodnou;
tata^.mkey := inform(temp1);
tata^.mptr := temp1;
tata^.rptr := nil;
frate^.lkey := inform(temp2);
frate^.lptr := temp2;
frate^.mkey := inform(temp3);
frate^.mptr := temp3;
frate^.rptr := nil;
end
else if nr < inform(temp2)
then
begin
tata^.mkey := nr;
tata^.mptr := nodnou;
tata^.rptr := nil;
frate^.lkey := inform(temp2);
frate^.lptr := temp2;
frate^.mkey := inform(temp3);
frate^.mptr := temp3;
frate^.rptr := nil;
end
________________________________________________________________________________
239
Structuri de date i algoritmi
_______________________________________________________________________________
begin
if head = nil then Insert_caz1(nr)
else if head^.tag = terminal then begin
if head^.key <> nr then Insert_caz2(nr)
end
else begin
caut_tata ;
if p^.rptr = nil then Insert_caz3
else begin
if ( nr <> p^.lkey) and (nr<>p^.mkey) and
(nr<>p^.rptr^.key) then
begin
240
Structuri de date i algoritmi
_______________________________________________________________________________
nou^.key := nr ;
Insert_caz4(nou) ;
succes := true ;
end ;
end ;
end ;
if succes then begin
writeln ( ' OK ! ' ) ;
Indicator ;
end
else writeln( ' Eroare ! Cheie dubla ! ' ) ;
end;
Procedure Inserare ;
begin
writeln ;
write( ' Introduce informaia: ' ) ;
readln (valoare) ;
succes := false ;
reset_stack ;
Inserare_arbore(valoare) ;
end ;
begin
write('Cheia de cutare: ');
readln(numar);
adr:=caut(head,numr);
if adr=nil
then begin
writeln('Element inexistent !');
readln;
end
else begin
writeln('Cutare cu succes !');
writeln('Numrul: ',adr^.key);
readln;
end;
end;
________________________________________________________________________________
241
Structuri de date i algoritmi
_______________________________________________________________________________
Function caut(p:adresa;x:integer):adresa;
begin
if p^.tag =terminal
then if p^.key=x
then caut:=p
else caut:=nil
else if x <= p^.lkey
then caut:=caut(p^.lptr,x)
else if (x > p^.lkey) and (x <= p^.mkey)
then caut:=caut(p^.mptr,x)
else if p^.rptr<>nil
then caut:=caut(p^.rptr,x)
else caut:=nil;
end;
begin
clrscr;
writeln('1 - inserare 2 - cutare esc - iesire');
head:=nil;
repeat
c:=readkey;
case c of
'1':begin
Inserare;
end;
'2' :begin
Cutare;
end;
end;
until c=#27;
end.
1. S se considere un arbore binar care cuprinde strmoii unei persoane, a crei nume figureaz n
rdcin arborelui. Nodul care figureaz n stnga cuprinde numele tatlui, iar cel din dreapta pe cel
al mamei. Fiind dat numele unei persoane oarecare din familie, s se afieze numele bunicilor, dac
acetia figureaz in arbore.
________________________________________________________________________________
242
Structuri de date i algoritmi
_______________________________________________________________________________
2. Reprezentai grafic arborele binar construit printr-o serie de inserri, pentru urmtorul ir de chei:
8, 17, 10, 15, 5, 2, 16, 19, 13, 1 , 4, 11.
3. Dup ce n elemente au fost nserate ntr-un arbore, ntr-o ordine aleatoare, care este numrul
mediu de comparaii necesare pentru a gsii al m lea cel mai mare numr ?
5. Formulai un algoritm specific care terge i rebalanseaz un arbore binar balansat n greutate .
6. Formulai un algoritm care s modifice un nod particular ntr-un ABCBG. Apelul algoritmului s
fie de forma:
SCHIMB ( CHEIE , GREUTATE_NOU )
unde CHEIE este cheia nodului care se modific i GREUTATE_NOU este noua greutatea a
nodului.
Observaie : GREUTATE _NOU poate s aib o valoare care poate cauza plasarea nodului la un
nivel superior sau inferior n arbore.
V.3.1. Introducere
________________________________________________________________________________
243
Structuri de date i algoritmi
_______________________________________________________________________________
Cea mai bun metod de cutare studiat pn acuma este cutarea binar, care are timpul
de cutare proporional cu O(log2n). Tehnicile de cutare discutate pn acum se bazeaz exclusiv
pe compararea cheilor.
O alt abordare posibil ar fi calculul direct al locaiei sau adresei unei date cutate. Evident
c ntr-un astfel de scenariu avem nevoie de o funcie special care s transforme informaia
corespunztoare cheii de cutare ntr-o adres unde s regsim informaia cutat. Expresia de
calcul este n mod natural dependent de mulimea cheilor de cutare i de spaiul de memorie
cerut de structura de date care va stoca informaiile dorite. De exemplu, dac utilizm o alocare
static cu ajutorul unui tabel pentru a nregistra date referitoare la cei n studeni a unei specializri,
atunci fiecare student poate fi identificat printr-un numr, avnd valoare ntre 1 si n. Dac
cunoatem locaia a-i-a a studentului cutat atunci scrierea student[i] va reprezenta accesul direct
la datele studentului cutat. O astfel de relaie cheie-adres exist rareori n aplicaii reale, deoarece
n general, cheile de cutare sunt alese fr a se ine seama de o astfel de consecinele implementrii
ntr-un limbaj de programare, a relaiei cheie-adres.
Din punct de vedere matematic, aceasta problem de transformare a cheii ntr-o adresa este
definit ca o funcie, numit funcie hash H, care face maparea spaiului de chei K ntr-un spaiu
de adrese A. Funcia hash trebuie s genereze o adres pe baza unui calcul simplu aritmetic sau
logic efectuat asupra cheii n totalitate sau asupra unei pri din cheie.
Datorit faptului c dimensiunea spaiului de chei este de obicei mai mare dect
dimensiunea spaiului de adrese, se poate ntmpla ca mai multor chei de cutare s le corespund,
prin intermediul funciei hash, o aceeai adres. Este evident implicaia pentru funcia de hash de a
nu avea proprietatea de injectivitate, adic:
k1 K , k 2 K , k1 k 2 H k1 H k 2 (5.x)
Acest fenomen se numete coliziune ntre nregistrrile memorate n structura de date.
Pentru a rezolva aceast problem este nevoie s analizm tehnici de rezolvare a coliziunilor, s
construim algoritmi corespunztori care s ne permit manipularea informaiilor stocate n structura
de date.
Funciile hash se grupeaz n dou mari clase:
Funcii hash independente-distribuional;
Funcii hash dependente-distribuional.
Clasa de funcii hash independente-distribuional nu folosete distribuia cheilor unei tabele
pentru calculul adresei unei nregistrri.
Clasa de funcii hash dependente-distribuional se folosete de distribuia unor chei din
punct de vedere probabilistic pentru calculul adresei unei nregistrri.
S vedem n continuare cteva exemple de funcii hash, dup care vom analiza operaiile i
algoritmii corespunztori manipulrii nregistrrilor ntr-o structur de date, precum i modaliti de
a rezolva problema coliziunilor.
________________________________________________________________________________
244
Structuri de date i algoritmi
_______________________________________________________________________________
Vom examina o serie de funcii hash simple. Dou dintre proprietile funciilor hash sunt
importante, i anume:
viteza mare de calcul a adresei;
distribuia uniform a adreselor.
f a c
(5.x)
f b d
Una dintre cele mai utilizate funcii hash este cea bazat pe metoda mpririi. Aceasta este
definit n felul urmtor:
H : K A, H x x mod m 1 (5.x)
unde m este un divizor ntreg nenul, iar operatorul mod este operatorul modulo, adic restul
mpririi lui x la m. Adresele generate de aceast funcie hash vor fi 1,2,3, , m.
________________________________________________________________________________
245
Structuri de date i algoritmi
_______________________________________________________________________________
O alt funcie hash care este folosit n multe aplicaii se bazeaz pe metoda ptratului
mediu. In aceast metod cheia de cutare este ridicat la ptrat, iar adresa unde va fi cutat
nregistrarea este obinut prin alegerea unui numr de cifre sau bii din mijlocul numrului obinut
prin ridicare la ptrat. Numrul de cifre ales este dependent de dimensiunea structurii de date care
stocheaz nregistrrile cutate.
De exemplu, s considerm o cheie din ase cifre: 123.456. Ridicm la ptrat i rezult
numrul 15.241.383.936. Dac avem nevoie de o adres format din trei numere, atunci putem alege
poziiile din mijloc de la 5 la 7, deci adresa va fi 138.
Pentru funcia hash bazat pe metoda ndoirii, numrul corespunznd cheii de cutare este
divizat n numere de lungime egal cu dimensiunea spaiului de adresare, cu o posibil excepie
corespunznd ultimei pri, care se poate completa cu zerouri nesemnificative pentru a avea aceeai
dimensiune cu celelalte diviziuni. Aceste pri sunt nsumate, este ignorat cifra carry, rezultatul
adunrii formnd adresa dorit.
Observaie: Dac cheia este binar, vom folosi operaia logic XOR n locul operaiei de
adunare.
Exemplu: Cheia de cutare 356.942.781 este mprit n trei numere de cte trei cifre pentru a
forma o adres de trei cifre, deoarece spaiul de stocare necesit cel mult 999 de locaii de memorie.
Cele trei numere obinute sunt 356, 942 si 781. Adunate, obinem:
356 +
942 renunm la cifra 2 de transfer i avem adresa 079.
781
--------
2079
________________________________________________________________________________
246
Structuri de date i algoritmi
_______________________________________________________________________________
Funcia hash, bazat pe metoda cifrelor formeaz adrese prin selectarea i translatarea cifrelor
din cheia de cutare original.
Exemplu: O cheie de cutare ce are valoarea numeric 7.546.123 este transformat n adresa 2164
prin selectarea cifrelor din poziiile 2 la 6 i inversarea ordinii lor.
Metoda de selectare i de inversare trebuie folosit cu consecven pentru o aceeai mulime
de chei de cutare. Pentru un set de chei aceeai poziie din cheie, aceeai rearanjare trebuie
folosit cu consisten.
O alta funcie hash des utilizat n structuri de date alocate static care folosesc tabele este
funcia hash bazat pe metoda dependent de lungimea cheii. n aceast metod lungimea cheii
este folosit singur sau mpreun cu o parte a cheii, pentru a produce direct o adres din tabel, ori
pentru a produce o cheie intermediar, care este folosit mai departe cu o alt metod, cum ar fi de
exemplu metoda mpririi, pentru a genera o adresa final din tabel.
O funcie hash de acest tip, sumeaz valoarea reprezentrii binare interne a primului i al
ultimului caracter al cheii i a lungimii cheii, translatat la stnga cu patru poziii binare (sau
multiplicat cu 24 = 16).
Exemplu: Avem cheia de cutare PROTEO. Ea va genera adresa:
215 + 214 + ( 6 * 16 ) = 525 dac utilizm codul EBCDIC.
Dac considerm 525 ca o cheie intermediar i aplicm metoda mpririi cu divizorul 49,
atunci adresa rezultat este 36.
Funcia hash bazat pe metoda codificrii algebrice are la baz teoria de codificare
algebric [Knu, 1976]. O cheie binar de n bii (k1 k2 ...kn)2 este codificat cu ajutorul unui polinom
de gradul n:
n
K x k i x i 1 (5.x)
i 1
Dac spaiul de adresare este n intervalul 0,2 m 1 , atunci vom construi un polinom
divizor al polinomului K, i anume:
m
P x x m p i x i 1 (5.x)
i 1
mprind polinomul K la polinomul P, folosind operaii n baza 2, vom obine polinomul
rest:
________________________________________________________________________________
247
Structuri de date i algoritmi
_______________________________________________________________________________
r
R x K x mod P x ri x i 1 (5.x)
i 1
[Knu, 1976] a artat, ca funciile hash de cutare bazate pe metoda multiplicativ sunt
printre cele mai performante. Dac x Z , iar c este o constant c pozitiv subunitar, 0 < c < 1,
atunci funcia hash arat n felul urmtor:
H x m cx 1 (5.x)
Am notat cu x cel mai mare ntreg mai mic dect x i cu x partea fracionar a lui x.
Aceast funcie hash d rezultate foarte bune dac constanta c este aleas corespunztor.
Alegerea constantei c este dificil.
[Knu, 1973], prezint studii asupra funciilor hash prezentate anterior. n general, aceste
funii hash genereaz adrese uniforme, dar o generalizare a acestei afirmaii este dependent de
mulimile particulare de chei de cutare.
Este nevoie de introducerea unui sistem de referin pentru a compara performanele
diferitele funcii hash. Cel mai larg acceptat criteriu de referin este ALOS (Average Length of
Search), prezentat n (5.1).
De obicei, cea mai performant funcie hash de folosit pentru un anumit mulime de cutare
va minimiza ALOS. Sunt ns i ali factori, n afar de performana funciilor hash, care
minimizeaz ALOS, timpul mediu de cutare.
V.3.4.1. Introducere
________________________________________________________________________________
248
Structuri de date i algoritmi
_______________________________________________________________________________
la aceeai adres a structurii de date. In practic, un astfel de fenomen se ntmpl pentru c spaiul
cheilor de cutare este mai mare dimensional dect spaiul adreselor. ntr-o astfel de situaie, funcia
hash nu este injectiv, deci dou sau mai multe chei de cutare pot genera prin intermediul funciei
hash aceeai adres. Evident, c nu putem suprapune dou sau mai multe nregistrri, cu chei de
cutare diferite, la aceeai adres generat de funcia hash.
Rezolvarea acestei probleme se face cu ajutorul tehnicilor de rezoluiune a coliziunilor.
Tehnicile de rezoluiune a coliziunilor se mpart n dou clase:
adresare deschis;
adresare nlnuit.
Obiectivul general al tehnicilor de coliziune, este de a ncerca plasarea nregistrrilor aflate
n coliziune la alte adrese ale structurii de date. Dac structura de date este o tabel, atunci ne
propunem s plasm nregistrrile aflate n tabel n alte locaii libere ale tabelei. Aceasta va implica
o serie de operaii de cutare n tabel, pn cnd gsim o poziie liber unde se poate insera una
din nregistrrile aflate n coliziune.
Deci avem nevoie de un mecanism i de algoritmul corespunztor care s examineze toate
poziiile structurii de date n vederea realizrii operaiilor de inserare, cutare, tergere, actualizare.
Un astfel de mecanism trebuie s satisfac o serie de cerine, i anume [Tom, 1997]:
viteza (pentru a determina repede o nou poziie liber);
puterea de acoperire (pentru a putea cuta n toate poziiile existente n structura de date);
reproductibilitatea (pentru a regsi nregistrrile inserate n structura de date).
Ideea de baz n tehnica de rezoluiune a coliziunilor prin adresare deschis este de a cuta
pentru nregistrarea aflat n coliziune o nou poziie liber n structura de date. Dac structura de
date este alocat static n memorie, atunci vom folosi o tabel pentru reprezentare, tabela se va numi
tabel hash. O astfel de tabel hash, fiind alocat static are un numr finit de poziii de stocare a
nregistrrilor, aceast capacitate ne putnd fi modificat pe parcursul execuiei programului ce
implementeaz algoritmul de manipulare a nregistrrilor. De aceea, pentru a folosi ct mai eficient
spaiul de stocare fix oferit de o tabel hash, va trebui s facem disponibile toate spaiile eliberate n
urma unor operaii de tergere.
Putem a gestiona aceast problem vom introduce marcaje care s ne indice faptul c o
poziie a tabelei hash este liber sau nu. Vom avea urmtoarele valori posibile pentru o poziie liber
din tabel hash, n cmpul cheii de cutare:
Emtpy poziie liber n tabela hash n care nu s-a inserat nici o nregistrare;
DELETED - poziie liber n tabela hash, unde a existat o nregistrare dar a fost tears:
Mecanismul prin care realizm cutarea unei noi adrese pentru o cheie de cutare aflat n
coliziune prin tehnica adresrii deschise este de mai multe feluri, i anume:
________________________________________________________________________________
249
Structuri de date i algoritmi
_______________________________________________________________________________
a. Probare liniar
b. Probare aleatoare
a. Probarea liniar
Unul din cele mai simple mecanisme de cutare a unei locaii libere pentru o nregistrare
avnd o cheie de cutare n coliziune, este de a folosii o secven de cutare liniar. Presupunnd c
avem cheia k K , H k a A , iar adresa la adresa a avem o coliziune, atunci probarea liniar se
bazeaz pe urmtoarea secven de cutare liniar:
unde m reprezint capacitatea maxim de stocare a tabelei. Vom gsi o locaie liber dac tabela nu
este deja plin.
Cnd efectum o operaie de cutare a unei nregistrri cu cheia de cutare k, vom proceda
astfel:
- calculm adresa corespunztoare cheii de cutare k: a H k A ;
- comparm cheia de la adresa a cu cheia de cutare k;
- Dac cheia de la adresa a este cea cutat, atunci avem o cutare cu succes:
- Dac cheia de la adresa a nu este cea cutat, pornim mecanismul de probare liniar (5.x).
Dac an ajuns la locaia de adres a 1, atunci cutare nu este cu succes, nregistrarea
cutat nu exist n tabel. Altfel cutarea este cu succes.
NINA H (NINA) = 1
STOICAN H (STOICAN) = 2
ANA H (ANA) = 3
ADA H (ADA) = 3
________________________________________________________________________________
250
Structuri de date i algoritmi
_______________________________________________________________________________
FUNCTIE H (FUNCTIE) = 9
B H (B) = 9
BRAND H (BRAND) = 9
PARAMETRU H (PARAMETRU) = 9
Dup operaia de inserare, aplicnd mecanismul probrii liniare, vom avea urmtoarea tabel:
Figura 5.x: Coninutul tabelei hash dup aplicarea operaiilor de inserare i a cutrii
unei noi poziii libere prin mecanismul de probare liniar.
Primele trei nregistrri, avnd cheile de cutare, NINA, STOICAN, ANA sunt inserate
printr-o singur probare n primele trei poziii libere (Empty) ale tabelei.
nregistrarea cu cheia de cutare ADA trebuie plasat n poziia 4 a tabelei cci poziia 3 este
ocupat i astfel apare o coliziune. Este nevoie de dou probri.
nregistrarea cu cheia de cutare FUNCTIE este inserat n poziia 9 de la prima operaie de
probare cci poziia 9 din tabel era liber (Empty).
nregistrrile cu cheile de cutare B si BRAND, sunt n coliziune cu nregistrarea cu cheia
de cutare FUNCTIE, respectiv B. Pentru a insera nregistrarea cu cheia de cutare B, aplicm
mecanismul probrii liniare i obinem poziia liber 10 din tabel, n urma a 2 operaii de probare.
Pentru a insera nregistrarea cu cheia de cutare BRAND, aplicm mecanismul probrii liniare i
obinem poziia liber 11 din tabel, n urma a 3 operaii de probare.
n final, nregistrarea cu cheia de cutare PARAMETER va fi plasat prin mecanismul
probrii liniare n poziia 5 a tabelei, necesitnd 8 operaii de probare, fiind n coliziune cu
nregistrrile inserate anterior, fiind probate poziiile ocupate 9, 10, 11, 1, 2, 3, 4 i poziia liber 5.
________________________________________________________________________________
251
Structuri de date i algoritmi
_______________________________________________________________________________
________________________________________________________________________________
252
Structuri de date i algoritmi
_______________________________________________________________________________
Operaia de tergere a unei nregistrri din tabela hash este simpl. Vom cuta nregistrarea
de ters din tabela hash. Dac nregistrarea exist, vom avea grij s marcm cmpul corespunztor
cheii de cutare cu marcajul DELETED. Acest marcaj este necesar pentru a optimiza operaiile de
cutare care se opresc n cazul unei cutri cu insucces dac avem valoarea marcajului DELETED,
i pentru a evita inserarea unor nregistrri cu cheie dubl. De exemplu n tabela (5.x), dac tergem
nregistrarea cu cheia de cutare FUNCTIE i nu marcm cmpul cheie cu marcajul DELETED,
atunci dac vrem s nserm o nou nregistrare cu cheia de cutare BRAND poziia 9 din tabela
hash va fi considerat liber i nregistrarea duplicat va fi inserat.
Specificarea problemei de tergere, avnd ca date de intrare tabela de hash tab, dimensiunea
maxim a tabelei m, cheia de tergere cheia, este urmtoarea:
n lucrarea [Knu, 1976] gsim un model probabilistic pentru a analiza tehnicile de rezoluie
a coliziune i calculare pentru determinarea performanelor algoritmului de cutare n cazul
mecanismului de probare liniar. Modelul presupune ca fiecare cheie este echiprobabil pentru
cutare. Dac notm cu m capacitatea maxim a tabelei hash, atunci probabilitatea ca o nregistrare
1
s fie cutat este p i .
m
Dac dimensiunea spaiului cheilor de cutare este n, atunci vom avea un numr de mn
________________________________________________________________________________
253
Structuri de date i algoritmi
_______________________________________________________________________________
funcii posibile de la K la A.
n
Vom nota cu factorul de ncrcare a tabelei hash . Timpul mediu de cutare va fi
m
dependent de factorul de ncrcare. n [Knu, 1976] gsim urmtoarea formul:
1 1
2 1 1 , pentru cautare cu succes
ALOS (5.x)
1
1 1 , pentru cautare cu insucces
2 1 2
b. Probarea aleatoare
Metoda probrii liniare are o serie de dezavantaje. Un prim dezavantaj este datorat faptului
ca trebuie s gestionm un indicator suplimentar de tergere, numit DELETED, n acest fel, o
nregistrare oarecare din tabel are trei stri, i anume, liber (Empty), ocupat sau tears
(DELETED). n mod normal, ar trebui ca o nregistrare din tabel s aib doar una din cele dou
stri posibile, i anume, liber sau ocupat.
Un alt dezavantaj al metodei de probare liniar este problema gruprii primare (primary
clustering). Acest fenomen apare datorit cutrii secveniale a unei poziii libere pentru
nregistrrile aflate n coliziune. De aceea, nregistrrile aflate n coliziune tind s se grupeze ntr-o
anumit poziie a tabelei, n loc ca ele s se distribuie ct mai uniform, fenomen care duce la
scderea performanelor algoritmului de cutare.
Efectele negative fenomenului ale gruprii primare, pot fi reduse prin selectarea unei alte
metode de probare, care s foloseasc un mecanism aleatoriu de cutare a unei poziii libere n
tabela hash, n loc de mecanismul de cutare secvenial. O astfel de metod de probare se numete
probare aleatoare (random probing)
Secvena de adrese de cutare pentru o poziie liber n tabela de hash va fi generat aleator,
dar va trebui s acopere toat mulimea de adrese cuprinse ntre 1 i m, exact o singur dat. O
tabel de hash va fi plin, n momentul n care, insernd o nou nregistrare, apelnd ca urmare a
coliziunii la mecanismul de probare aleatoare, se genereaz aleatoriu o adres duplicat [Tre, 1984].
Un exemplu de mecanism de generare aleatoare a adreselor pentru o tabel hash este :
a := ( a + c ) mod m (5.x)
unde a este adresa iniial generat de funcia hash, c este o constant ntreag, nenul, aleas astfel
________________________________________________________________________________
254
Structuri de date i algoritmi
_______________________________________________________________________________
Problemele legate de tergere devin i mai severe n cazul probrii aleatoare, dect n cazul
probrii liniare. Dei probarea aleatoare rezolv problema gruprii primare, din pcate nu elimin
problema gruprii secundare (secondary clustering). Gruparea secundar apare cnd se genereaz
aceeai secven de adrese libere pentru dou chei de cutare aflate n coliziune.
O soluie pentru problema gruprii secundare, este de a folosii o funcie hash secundar
care s genereze o valoare aleatoare pentru constanta c din formula (5.x), independent de prima
funcie hash. Prin aplicarea acestei metode se anuleaz efectul negativ al gruprii.
Fie H 1 : K A prima funcie de hash, i k1 , k 2 K dou chei de cutare distincte aflate n
coliziune, adic:
H 1 k1 H 2 k 2 a A
________________________________________________________________________________
255
Structuri de date i algoritmi
_______________________________________________________________________________
Fie H 2 : K A a doua funcie de hash, folosit pentru a genera valoarea constantei c din
formula de probare aleatoare (5.x). Atunci dac H 2 k1 H 2 k 2 putem alege c H 2 k1 . n acest
fel, la fiecare probare aleatoare se vor genera secvene diferite de adrese, iar problema gruprii
secundare va fi depit.
Metoda descris mai sus de a folosi dou funcii hash independente se numete hash dublu.
begin
i := hashfunction( key ) ;
inc := increment( key ) ;
last := (i+(n-1)*inc) mod m;
while (i<>last) and (not empty(r[i])) and (r[i].k<>key) do
i := (i+inc) mod m;
if r[i].k=key then search := i {*** cutare cu succes ***}
else search := -1; {*** cutare fr succes ***}
end;
________________________________________________________________________________
256
Structuri de date i algoritmi
_______________________________________________________________________________
umplere de 95 %, numrul mediu de operaii pentru metoda probrii liniare este 10,5, pe cnd la
metoda probrii aleatoare cu dublu hash este 3,2!
O alta metod de a rezolva problema coliziunilor este acea de a grupa cheile de cutare
aflate n coliziune n clase de echivalen. Reprezentantul unei clase de echivalen va fi capul unei
liste simplu nlnuite cu ajutorul creia se vor gestiona dinamic toate cheile de cutare aflate n
aceeai clas de coliziune, adic toate cheile de cutare care genereaz aceeai adres:
H : K A, K k1 , k2 , , kq , k i , k j kl , dac H k i H k 2 k i
Vom avea in acest fel o tabel hash fix, de dimensiune m mai mare sau egal cu numrul
claselor de echivalen. n aceast tabel hash vom stoca doar cheia de cutare reprezentant al clasei
de echivalen i adresa de nceput a listei simplu nlnuite care stocheaz restul cheilor de cutare
aflate n coliziune cu cheia reprezentant al clasei de echivalen.
Aceast tehnic de rezoluiune a coliziunilor se numete adresare nlnuit.
Exemplu: n figura de mai jos avem un exemplu de reprezentare a metodei adresrii nlnuite,
pentru m = 11 si n = 9. Presupunem c cheile sunt nserate n ordinea urmtoare :
________________________________________________________________________________
257
Structuri de date i algoritmi
_______________________________________________________________________________
Specificarea problemei de inserare, avnd ca date de intrare tabela hash numit tab,
dimensiunea maxim a tabelei m, cheia de inserare cheia, este urmtoarea:
Specificarea problemei de cutare, avnd ca date de intrare tabela hash numit tab, cheia de
cutare cheia_caut, este urmtoarea:
________________________________________________________________________________
258
Structuri de date i algoritmi
_______________________________________________________________________________
@returneaz NIL;
ALTFEL
adr := caut_list (LIST, cheia_caut); {se caut n lista simplu nlnuit }
DAC adr = NIL ATUNCI
TIPRETE (EROARE CUTARE inf. nu exist);
@returneaz NIL;
ALTFEL
@returneaz adr;
SFDAC
SFDAC
SFALGORITM
Performana algoritmului de cutare bazat pe adresare nlnuit este, conform [Tre, 1984]:
1 , pentru cutar cu succes
ALOS 2 (5.x)
e , pentru cutar cu insucces
4. Cte probri sunt necesare, cnd este folosit tehnica probrii aleatoare pentru a insera n chei de
________________________________________________________________________________
259
Structuri de date i algoritmi
_______________________________________________________________________________
cutare egale?
5. Care metoda de probare este mai eficient n situaia n care se insereaz mai multe chei de
cutare egale ?
6. S presupunem c numrul de nregistrri care trebuie inserate ntr-o tabel hash este cunoscut n
prealabil. n ce condiii metoda adresrii nlnuite este preferabil fat de metoda adresrii
deschise?
7. Folosind metoda divizrii, calculai adresa generat de funcia hash pentru urmtoarele seturi de
chei de cutare: PAX, ARC, RATE i NUMR. Se va folosi reprezentarea ASCII a cheilor de
cutare i m = 111.
9. Avem urmtoarele chei de cutare numerice: 66, 47, 87, 90, 126, 140, 145, 153, 177, 285, 393,
395, 476, 566, 620, 735. Stocai nregistrrile ntr-o tabel hash cu 20 de poziii, folosind metoda
divizrii pentru funcia hash i metoda probrii liniare pentru rezolvarea coliziunilor.
10. Folosind aceleai chei de cutare ca la exerciiul 9, stocai nregistrrile ntr-o tabel hash cu 20
de poziii folosind metoda mpririi pentru funcia hash i metoda probrii aleatoare pentru
rezolvarea coliziunilor.
VI.TEHNICI DE SORTARE
VI.1. ISTORIC
Cutarea originii metodelor actuale de sortare ne conduce n secolul al XIX-lea, cnd au fost
inventate primele maini de sortat. n Statele Unite, cu ocazia recensmntului din 1880, Herman
Hollerith, angajat al Biroului de Recensmnt, a inventat o main electric de tabelat pentru a
rspunde necesitilor de prelucrare statistic. Un om putea prelucra 49 de cartele pe minut. n 1901
a inventat o main mai modern care lucra automat. Maina de sortat al lui Hollerith este baza
metodelor de sortare dup ranguri, folosite n prezent pe calculatoare.
Ideea interclasrii provine de la o alt main cu cartele, numit "collator" din 1938, care
putea interclasa dou pachete de cartele ntr-unul singur, ntr-o singur trecere.
Primul program scris pentru un calculator cu program memorat a fost o rutin de sortare. John von
Neumann a pregtit programe de sortare intern n 1945, pentru a testa valabilitatea unor coduri de
instruciuni propuse de el pentru calculatorul ENIAC. Jonh Mauchly a confereniat despre "Sortare
________________________________________________________________________________
260
Structuri de date i algoritmi
_______________________________________________________________________________
si Fuziune" la sesiunea special asupra calculatoarelor inut la Moore School n 1946, iar notele
acestei conferine constituie prima discuie public a sortrii pe calculator. Prima metod de sortare
folosea numrarea comparaiilor; apoi urmau o serie de treceri de interclasare echilibrat cu dou
ci.
n 1952 Daniel Goldenberg, a codificat 5 metode diferite: interclasarea direct cu dou ci,
sortarea cu baz 2, selecia direct, metoda bulelor. Seward a introdus idea de numrare a
distribuiilor si de selecie cu nlocuire.
Astfel istoria sortrii este strns legat de multe premiere din domeniul calculatoarelor:
primele maini de prelucrare a datelor primele programe memorate, primul software, primele
metode de utilizare a zonelor tampon de intrare-ieire, primele lucrri asupra analizei algoritmilor si
asupra complexitii calculelor.
n 1959 Donald L. Shell a propus sortarea prin micorarea incrementului; sortarea cu
interclasare si interschimb a fost descoperit de K. E. Batcher n 1964; C. A. R. Hoare a descoperit
metoda sortrii rapide; n 1964 a fost descoperit sortarea de ansambluri de ctre J. W. J. Williams.
Pe parcursul anilor s-au mbuntit aceste metode de sortare si s-au descoperit si metode noi,
metode hibride.
n acest capitol vom prezinta pe scurt cele mai importante informaii despre caracteristicile
principalelor metode de sortare i a algoritmilor corespunztori, ncepnd de la cele mai simple
metode de sortaare pn la cele complexe metode de sortare, folosind diferite structuri de date:
matrice, liste nlnuite, stive, arbori, ., etc.
Exist urmtoarea clasificare a metodelor de sortare [Lew, 1991]:
Metode de sortare simple : selecie, inserare, bule, Shell;
Metode de sortare complexe : rapid, interclasare, ansambluri, Radix.
Metodele simple de sortare au de obicei complexitatea O(N2) adic pot sorta N elemente
ntr-un timp proporional cu N2 si sunt eficiente pentru tabele mici n care numrul de elemente este
mai mic dect 500. Totui, pentru multe aplicaii de sortare este mai bine s folosim metode simple
dect complexe. De exemplu, dac tabela este deja sortat, n cazul metodei de sortare rapid
pivotul ales (elementul n jurul creia se face sortarea) este primul element, metoda de sortare prin
selecie este mai rapid. Metodele simple sunt ntotdeauna mai potrivite pentru un numr de
elemente mai mic dect 50. Tabelele parial sau total sortate, sau cele care conin un numr mare de
chei identice, sunt relativ uor de sortat cu ajutorul algoritmilor simplii. Necesit relativ puin timp
de programare si ntreinere.
Metodele complexe pot sorta N elemente ntr-un timp proporional cu NlogN. Nici un
algoritm nu poate folosi mai puin de NlogN comparaii ntre chei. Aceste metode complexe sunt
eficiente mai ales pentru sortarea unui numr mare de elemente. Necesit mai mult timp pentru
programare dar sunt mai eficiente. Unul dintre cei mai populari algoritmi de sortare cu scop general
________________________________________________________________________________
261
Structuri de date i algoritmi
_______________________________________________________________________________
este sortare rapid (Quicksort), care are o complexitate de O(NlogN), exprimat pentru mediu
necesar operaiei de sortare. Acest algoritm de sortare are performane bune n general, chiar dac n
caz nefavorabil complexitatea devine O(N2).
Ideea "divide et impera" a fost aplicat problemelor de sortare n mai multe feluri rezultnd
urmtorii algoritmii de sortare: rapid, interclasare, ansambluri, Radix care sunt mult mai eficiente
dect cele simple. Sortarea prin ansambluri si sortarea prin interclasare au complexitatea egal cu
O(NlogN), dei n cazul general comportarea lor nu este chiar aa de bun ca la algoritmul de
sortare rapid. Exist metode care folosesc proprietile digitale ale cheilor ca s obin o
complexitate proporional cu N, ca de exemplu sortarea Radix.
La baza studiului complexitii unui algoritm st detectarea, n descrierea algoritmului, a
operaiei sau a operaiilor de baz, adic acea operaie aflate n cel mai interior corp de ciclu
repetitiv si a crei analiz permite estimarea n avans, nainte de lansarea n execuie, a algoritmului
ce descrie metoda de sortare respectiv.
n majoritatea cazurilor exist o legtur foarte strns ntre operaia de baz (cea mai repetat
operaie) si operaia care este dedus n etapa de analiz a problemei ca fiind operaia inevitabil
pentru rezolvarea problemei.
De exemplu, n cazul problemei sortrii unui sir de N chei prin comparaii este limpede c
operaia de comparare a mrimii cheilor este operaia inevitabil si de asemenea ea va fi i
operaia de baz a crei contorizare va permite estimarea, nainte de execuia programului ce
implementeaz algoritmul, a duratei de execuie a programului ce implementeaz algoritmul de
sortare respectiv.
n aceast situaie, toi algoritmii diferii care soluioneaz aceeasi problem si care se
bazeaz pe aceeai operaie de baz (inevitabil) formeaz clasa algoritmilor de soluionare a
problemei. De obicei numele clasei va fi dat chiar de numele acelei operaii de baz ce este
coninut de fiecare algoritm al clasei n mod inevitabil.
De exemplu, n cazul problemei sortrii unui sir de N chei prin comparaii, algoritmii diferii
ce soluioneaz aceast problema sunt grupai n clasa algoritmilor de sortare prin comparaii, spre
deosebire de clasa algoritmilor de sortare prin distribuire ce soluioneaz aceeai problem
bazndu-se ns pe alt operaie de baz: distribuirea cheilor de sortat.
Astfel, algoritmi de sortare prin comparare descrii in aceasta lucrare sunt: algoritmul de
sortare prin inserare, algoritmul de sortare prin selecie, algoritmul de sortare Shell, algoritmul de
sortare combinat, algoritmul de sortare simplu, algoritmul de sortare rapid, algoritmul de sortare
prin ansambluri, algoritmul de sortare prin interclasare, iar algoritm de sortare prin distribuire este
algoritmul de sortare Radix.
Compararea eficienei a doi algoritmi diferii ce soluioneaz aceeai problem se face prin
determinarea teoretic a numrului de repetiii a operaiei de baz n fiecare algoritm si compararea
celor dou valori. n final rezultatul comparrii va permite estimarea comparativ a timpului de
sortare a programelor ce implementeaz acei algoritmi i alegerea celui mai bun.
Compararea eficientei a doi algoritmi din punct de vedere practic se face prin compararea
timpilor medii de execuie a celor dou programe ce i implementeaz. Aceast metod pragmatic
are dezavantajul c necesit rularea programelor care, n anumite situaii, poate dura un timp
surprinztor de mare.
________________________________________________________________________________
262
Structuri de date i algoritmi
_______________________________________________________________________________
Analiznd complexitatea algoritmilor factorul cel mai important este timpul de execuie
exprimat prin "O-mare". Trebuie s folosim mai multe criterii pentru evaluarea timpului de execuie
al algoritmului de sortare cum ar fi, numrul de pai ai algoritmului si numrul de comparaii dintre
chei necesare pentru a sorta N elemente. Aceast msur este de folos cnd compararea dintre
perechile de chei este costisitoare, cnd cheile sunt iruri lungi de caractere, sau cnd mrimea
nregistrrii este mare.
Al doilea factor important este cantitatea (volumul) de memorie suplimentar folosit de un
algoritm de sortare. Metodele se mpart n trei tipuri: cei care sorteaz pe loc, nu folosesc memorie
suplimentar, cu excepia poate unei tabele sau stive mici; cei care au o reprezentare de list
nlnuit deci folosesc N cuvinte de memorie n plus pentru pointerii listei; cei care au nevoie de
memorie suplimentar pentru o copie a tabelei iniiale.
Caracteristica care este uneori important n practic este stabilitatea. O metod de sortare
este stabil dac pstreaz ordinea relativ a cheilor egale n tabel. (Dac sortm un sir de nume,
numele cu aceeai liter de nceput sunt sortate n ordine alfabetic). Majoritatea metodelor simple
sunt stabile dar muli dintre algoritmii de sortare compleci nu au aceast proprietate.
________________________________________________________________________________
263
Structuri de date i algoritmi
_______________________________________________________________________________
264
Structuri de date i algoritmi
_______________________________________________________________________________
Fie dat o tabel A cu N nregistrri Ri, fiecare nregistrare avnd cheia de cutare Ki. Pentru
sortarea tabelei este nevoie de N-1 pai.
Parcurgem tabela n felul urmtor: comparm cheia primului element K1, cu cheia celui de al
doilea element K2 i dac nu sunt n ordine cresctoare, interschimbm primul element R1 cu cel de-
al doilea element R2.
Procesul se repet pentru nregistrrile R2, R3,, RN.. Dup prima parcurgere a tabelei,
nregistrarea cu cea mai mare cheie va ajunge pe ultima poziie N a tabelei.
n continuare vom lua n considerare primele N 1 nregistrri. Dup aceea vom lua n
considerare primele N -2 nregistrri, , etc. Dup fiecare pas, elementele cu chei mari vor ajunge
pe poziiile N - 1, N - 2, , 2, n final rezultnd o tabel sortat n ordine cresctoare.
Exemplul VI.1: Sortarea tabelei A din Figura VI.1, n ordine cresctoare, folosind algoritmul de
sortare prin metoda bulelor:
Pasul 1: Prelucrm primele 10 nregistrri ale tabelei.
- comparm 6 cu 4, interschimbm;
- comparm 6 cu 5 si interschimbm:
- comparm 6 cu 10, nu interschimbm;
- comparm 10 cu 3, interschimbm;
- comparm 10 cu 1, interschimbm;
- comparm 10 cu 8, interschimbm;
- comparm 10 cu 9, interschimbm;
- comparm 10 cu 7, interschimbm;
- comparm 10 cu 2, interschimbm;
nregistrarea cu cheia cea mai grea, 10, a ajuns la partea inferioar a tabelei.
Pasul 2: Prelucrm primele 9 nregistrri ale tabelei.
- comparm 6 cu 4, interschimbm;
- comparm 4 cu 5 si nu interschimbm:
- comparm 5 cu 6, nu interschimbm;
- comparm 6 cu 3, interschimbm;
- comparm 6 cu 1, interschimbm;
- comparm 6 cu 8, nu interschimbm;
- comparm 8 cu 9, nu interschimbm;
- comparm 9 cu 7, interschimbm;
________________________________________________________________________________
265
Structuri de date i algoritmi
_______________________________________________________________________________
- comparm 9 cu 2, interschimbm;
nregistrarea cu cheia cea mai grea, 9, a ajuns la partea inferioar a tabelei.
..
Algoritmul de sortare prin metoda bulelor ordoneaz cele 10 nregistrri ale tabelei A n 8
pai.
Figura VI.1. Sortarea unei tabele A cu 10 elemente prin algoritmul de sortare bazat pe metoda
bulelor.
DATE A, N;
REZULTATE A; { tabela A sortat n ordine cresctoare }
________________________________________________________________________________
266
Structuri de date i algoritmi
_______________________________________________________________________________
Ok := TRUE;
PENTRU i := 1;k EXECUT
DAC A[i] > A[i+1] ATUNCI
temp := A[i];
A[i] := A[i+1];
A[i+1] := temp;
Ok := FALSE;
SFDAC
SFPENTRU
k := k -1;
PNCND Ok SFREP
SFALGORITM
Procedure bubble;
Begin
K := n;
Repeat
Ok := true;
For i := 1 to k do
If A[i] >A[i+1] then
Begin
temp := A[i];
A[i] := A[i+1];
A[i+1] := temp;
Ok := false;
End;
k :=k-1;
Until Ok;
End;
Algoritmul de sortare prin metoda bulelor este o metod de sortare simpl, eficient pentru
un numr mic de elemente (mai puin de 15), dar nu pentru tabele mari.
Nu necesit mult memorie, dar este de dou ori mai lent dect algoritmul de sortare prin
inserare n aproape orice situaie. Timpul de execuie depinde de structura iniial a datelor de
intrare, adic de ordinea iniial al elementelor [Ski, 1997]. Dac tabela de dimensiune N este deja
sortat e nevoie de un singur pas, adic de N-1 operaii de comparaie, n aceast situaie algoritmul
________________________________________________________________________________
267
Structuri de date i algoritmi
_______________________________________________________________________________
Selecia direct este una dintre cele mai simple metode de sortare ce are performane foarte
bune pentru tabele mici, fiecare element (nregistrare) al tabelei, fiind mutat n procesul de sortare
cel mult o dat. Este o metod de sortare liniar pentru nregistrri lungi si chei de cutare mici.
Implementarea algoritmului este simpl, dar necesit spaiu de memorie destul de mare pentru a
stoca dou tabele, acest lucru fiind un neajuns al algoritmului de sortare.
Se caut cel mai mic element din tabela de sortat A si se schimb cu elementul de pe
prima poziie. Dup aceea se caut al doilea element minim si se schimb cu elementul de
pe poziia a doua, .a.m.d. n general, n pasul i se selecteaz elementul cu cea mai mic
cheie dintre nregistrrile A[i], A[i+1],, A[N] si se schimb cu A[i]. Ca rezultat, dup i
pai, al i-lea element minim va ocupa poziiile A[i], A[i+1],, A[N] n ordine sortat. Se
continu pn cnd toate elementele vor fi sortate n ordine cresctoare.
Exemplul VI.2: Sortarea tabelei A din Figura VI.2 folosind algoritmul de sortare prin selecie, n
ordine cresctoare:
________________________________________________________________________________
268
Structuri de date i algoritmi
_______________________________________________________________________________
Figura VI.2. Sortarea unei tabele A cu 10 elemente prin algoritmul de sortare prin selecie.
..
Algoritmul de sortare prin metoda seleciei ordoneaz cele 10 nregistrri ale tabelei A n 8
pai.
269
Structuri de date i algoritmi
_______________________________________________________________________________
DATE A, N;
REZULTATE A; { tabela A sortat n ordine cresctoare }
________________________________________________________________________________
270
Structuri de date i algoritmi
_______________________________________________________________________________
End;
End;
Algoritmul de sortare prin metoda seleciei este o metod de sortare eficient pentru un
numr mic de elemente de sortat, dar nu pentru tabele mari.
Operaiile cele mai costisitoare sunt cele de cutare a nregistrrii cu cheia minim din
partea rmas nesortat n tabel. Dup fiecare pas de cutare este necesar o intershimbare, deci
numrul interschimbrilor pentru N elemente este N - 1. Numrul total de operaii de comparaie
pentru a gsi cheia minim este [Knu, 1976]:
n 1
n n 1 n n 1
n i n n 1
i 1 2
2
performane se obin i n medie i n cazul cel mai nefavorabil, chiar i atunci cnd tabela este deja
sortat. Dac avem nregistrri mari si chei mici, algoritmul de sortare prin metoda seleciei va fi
alegerea cea mai bun.
Este un algoritm aproape la fel de simplu ca algoritmul de sortare prin selecie, dar poate
mai flexibil.
Dac considerm c elementele A[1]...A[i-1] sunt deja sortate, atunci va trebui s inserm
elementul A[i] n locul potrivit pentru a menine ordinea de sortare aleas.
Fiind dat o tabel A cu N elemente nesortate, parcurgem tabela si inserm fiecare element
n locul potrivit pentru a menine ordinea de sortare aleas ntre celelalte elemente considerate deja
sortate.
Pentru fiecare i = 2,.., N , dac elementele A[1], A[2],, A[i] sunt sortate, vom insera
elementul A[i] ntre lista elementelor sortate: A[1], A[2],, A[i].
Elementele aflate n stnga indexului i sunt sortate dar nu sunt nc n poziia lor final.
Tabela este complet sortat cnd indexul ajunge la captul drept al tabelei.
________________________________________________________________________________
271
Structuri de date i algoritmi
_______________________________________________________________________________
Putem uura procesul inserrii (ex: cnd cel mai mic element e greu de definit), prin introducerea
unul element de "limit" A[0], cheia care va avea o valoare mai mic dect orice valoare posibil a
unei chei din tabel. Vom considera c aceast cheie are valoarea .
Exemplul VI.3: Sortarea tabelei A din Figura VI.3 folosind algoritmul de sortare prin inserare,
n ordine cresctoare:
A[j] 6 4 5 10 3 1 8 9 7 2
pas 1 4 6 5 10 3 1 8 9 7 2
pas 2 4 5 6 10 3 1 8 9 7 2
pas 3 4 5 6 10 3 1 8 9 7 2
pas 4 3 4 5 6 10 1 8 9 7 2
pas 5 1 3 4 5 610 8 9 7 2
pas 6 1 3 4 5 6 8 10 9 7 2
pas 7 1 3 4 5 6 8 910 7 2
pas 8 1 3 4 5 6 7 8 910 2
pas 9 1 2 3 4 5 6 7 8 9 10
Figura VI.3. Sortarea unei tabele A cu 10 elemente prin algoritmul de sortare prin inserare.
________________________________________________________________________________
272
Structuri de date i algoritmi
_______________________________________________________________________________
..
Algoritmul de sortare prin metoda inserrii ordoneaz cele 10 nregistrri ale tabelei A n 9
pai.
DATE A, N;
REZULTATE A; { tabela A sortat n ordine cresctoare }
________________________________________________________________________________
273
Structuri de date i algoritmi
_______________________________________________________________________________
Algoritmul de sortare prin inserare sort este un algoritm de sortare liniar: Complexitatea
algoritmului este O(N) pentru tabele care conin N elemente sortate sau aproape sortate.
Complexitatea algoritmului de sortare prin inserare depinde de numrul de inserri i
N2
translatri, care este influenat de ordinea iniial al elementelor. n caz general sunt necesare 4
N2
operaii de comparaie i 8 operaii de interschimbare, deci ordinea complexitii este O(N2).
[Tre, 1984]
Sortarea prin micorarea incrementului, numit i sortare Shell este o extensie simpl al
________________________________________________________________________________
274
Structuri de date i algoritmi
_______________________________________________________________________________
Dac sortm fiecare din cele h subtabele, folosind de exemplu algoritmul de sortare prin
inserare, atunci elementele ndeprtate se vor apropia, srind cu pasul h ctre stnga. n final, vom
proceda la o sortare prin inserare cu incrementul 1, ceea ce va necesita un timp foarte scurt cci
tabela nu mai necesit corecii importante, majoritatea nregistrrilor fiind n poziia cresctoare
dorit.
Algoritmul de sortare Shell, necesit o mulime de incremeni ht , ht 1 , , h1 , ultimul
increment h1 fiind egal cu 1.
O formula des utilizat n practic propune urmtoarele formule pentru secvena de
incremeni:
h1 1; hi 1 3hi 1 (6.1)
Secvena este 1,4,13, 40, 121, ., cu formula general:
3i 1
hi (6.2)
2
Deci numrul total de incremeni va fi:
t log 3 2n 1 (6.3)
Algoritmul de sortare Shell necesit mai multe operaii dect algoritmul de sortare prin
inserare, dar la fiecare pas elementele ce urmeaz a fi interschimbate efectueaz salturi lungi spre
poziia corect, ceea ce ar trebui s duc la mbuntirea performanelor algoritmului de sortare.
n general, algoritmul de sortare Shell poate fi descris astfel [Aho, 1997]:
________________________________________________________________________________
275
Structuri de date i algoritmi
_______________________________________________________________________________
Exemplul VI.4: Sortarea tabelei A din Figura VI.4 (a) folosind algoritmul de sortare Shell, n ordine
cresctoare:
A[ ] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9] A[10] A[11] A[12]
(a) 11 10 9 8 7 6 5 4 3 2 1 0
(b) 11 6 1
10 5 0
9 4
8 3
7 2
(c) 1 6 11
0 5 10
4 9
3 8
2 7
(d) 1 0 4 3 2 6 5 9 8 7 11 10
(e) 0 1 2 3 4 5 6 7 8 9 10 11
Figura VI.4. Sortarea unei tabele A cu 12 elemente prin algoritmul de sortare Shell.
________________________________________________________________________________
276
Structuri de date i algoritmi
_______________________________________________________________________________
Pasul 3: Tabela iniial dup pasul de sortare cu incrementul 5 (Fig. VI.4. (d))
Pasul 3: Tabela iniial dup pasul de sortare cu incrementul 1 (Fig. VI.4. (d))
..
DATE A, N;
REZULTATE A; { tabela A sortat n ordine cresctoare }
________________________________________________________________________________
277
Structuri de date i algoritmi
_______________________________________________________________________________
Observaie:
Secvena de incrementare este determinat iterativ, folosind funciile Increment_intial(n) i
Increment_urmtor(inc, n). Funcia Increment_intial(n) va returna cel mai mare increment
utilizabil pentru sortarea unei tabele de dimensiune n.
Funcia Increment_urmtor(inc, n) va returna cel mai mare increment dar mai mic dect inc,
utilizabil pentru sortarea unei tabele de dimensiune n.
Funciile Increment_intial(n) i Increment_urmtor(inc, n) vor genera irul descresctor de
incremeni ht , ht 1 , , h1 =1.
Se presupune c Increment_urmtor(1, n) = 0. Ciclul exterior se va termina cnd inc = 1.
________________________________________________________________________________
278
Structuri de date i algoritmi
_______________________________________________________________________________
Complexitatea algoritmului de sortare Shell sort este greu de analizat, greu de comparat cu
alte metode, fiind dependent i de mulimea de incremeni. Pentru acest algoritm de sortare,
cercetri empirice au artat c complexitatea este, n general O N log N [Aho, 1997]. Exist
mulimi de incremeni pentru care s-a dovedit c complexitatea este O N log N 2 . Nu se cunoate
pn n prezent o mulime optimal de incremeni pentru algoritmul de sortare Shell.
Algoritmul de sortare, considerat a fi cel mai rapid, de complexitate O N log N este numit
algoritm de sortare rapid (quicksort), folosind partiionarea ca idee de baz. Este mai rapid dect
orice metod de sortare simpl, se comport eficient pentru fiiere sau tabele mari, dar ineficient
pentru cele de mici dimensiuni.
Strategia de baz are la baz o tehnic de tip "divide et impera" [Liv, 1986], pentru c este
mai uor de sortat dou tabele mici, dect o tabbel mare. Algoritmul este uor de implementat,
consum mai puine resurse dect orice alt metod de sortare.
________________________________________________________________________________
279
Structuri de date i algoritmi
_______________________________________________________________________________
- algoritmul mut pe i la dreapta, pn cnd gsete o cheie mai mare dect pivotul v si mut
pe j la stnga pn cnd gsete o cheie mai mic dect pivotul v.
- dac nu este necesar interschimbarea se decrementeaz j cu 1 si se repet procesul de
comparaie;
- dac apare un interschimb, se incrementeaz i cu 1 si se continu compararea, mrind i pn
la apariia unui nou interschimb;
- se decrementeaz j, continundu-se acest proces de numit "ardere a lumnrii la ambele
capete", pn cnd i >= j.
Procedura se apeleaz recursiv printr-un apel de forma: SORTARE_Rapida(A, 1, N);
Exemplul VI.5: Sortarea tabelei A din Figura VI.4 (a) folosind algoritmul de sortare Shell, n ordine
cresctoare:
Pasul 2: Caut de la stnga la dreapta elementul cu cheia mai mare dect 7 (indexul i)
- Acesta este 8, comparm pe 7 cu 8, 8 > 7, i interschimbm;
Pasul 3: Caut de la dreapta la stnga elementul cu cheia mai mic dect 7 (indexul j)
- Acesta este 6, i interschimbm cu elementul de pe poziia i;
Procesul de "ardere a lumnrii la ambele capete" se continu pn cnd i >= j, atunci tabela
se mparte n dou subtabele care se sorteaz separat recursiv pn cnd fiecare subtabel va conine
doar un element.
________________________________________________________________________________
280
Structuri de date i algoritmi
_______________________________________________________________________________
Figura VI.5. Sortarea unei tabele A cu 12 elemente prin algoritmul de sortare Shell.
DATE A, N;
REZULTATE A; { tabela A sortat n ordine cresctoare }
________________________________________________________________________________
281
Structuri de date i algoritmi
_______________________________________________________________________________
SFALGORITM
n algoritmului de sortare rapid, fiecare element este comparat cu pivotul, adic avem
complexitatea O(N).
In continuare tabela este divizat n dou pri, fiecare parte este iari divizat n dou pari,
., .a.m.d. Dac fiecare parte este mprit aproximativ n dou jumti egale, vom avea log 2N
operaii de mprire.
Deci complexitatea algoritmului de sortare rapid este n caz mediu O(Nlog2N), iar n caz
nefavorabil este O N 2 [Knu, 1976].
Dup cum am artat mai sus, algoritmul de sortare rapid este o metod bun n cazul
general, dar nu i n cazul nefavorabil, cnd este preferabil alegerea pivotului conform formulei
________________________________________________________________________________
282
Structuri de date i algoritmi
_______________________________________________________________________________
(6.2). Performanele algoritmului de sortare rapid sunt dependente de ordinea datelor de intrare. De
aceea nu este o metod de sortare stabil.
Algoritmul de sortare prin interclasare se bazeaz pe urmtoarea idee: pentru a sorta o tabel
cu N elemente, mprim tabela iniial n dou subtabele pe care le sortm separat si le interclasm.
Este o metod de sortare care folosete ca strategie de baz tehnica "divide et impera", conform
creia o problema care se poate descompune n alte dou subprobleme de acelai tip, se rezolv cale
dou subprobleme, iar rezultatele subproblemelor se combin pentru a genera rezultatul problemei
iniiale. Algoritmul de sortare prin interclasare sorteaz elementele n ordine cresctoare.
Fiind dat o tabel A cu N elemente, mprim tabela n dou pri, sortm separat fiecare
parte si mbinm prin interclasare cele dou pri ntr-o tabel auxiliar temporar. Dac o parte
conine doar un singur element, atunci considerm acea parte sortat.
mbinarea celor dou pri necesit un numr de operaii de ordinul O(N). Algoritmul se
termin cnd o subtabel nu mai are nici o nregistrare si mutm nregistrrile rmase din cealalt
subtabel n tabela temporar. Dup pasul de interclasare putem copia tabela temporar sortat n
tabela original.
________________________________________________________________________________
283
Structuri de date i algoritmi
_______________________________________________________________________________
________________________________________________________________________________
284
Structuri de date i algoritmi
_______________________________________________________________________________
Figura VI.7. Sortarea unei tabele A cu 9 elemente prin algoritmul de sortare prin interclasare.
DATE A, N;
REZULTATE A; { tabela A sortat n ordine cresctoare }
________________________________________________________________________________
285
Structuri de date i algoritmi
_______________________________________________________________________________
Index_curent_drept := Index_curent_drept + 1;
@Copiaz toate elemente rmas din jumtatea stng n tabela Temp;
@Copiaz toate elemente rmas din jumtatea deapt n tabela Temp;
@Copiaz toate elemente sortate din tabela Temp n tabela A;
SFALGORITM
Variabilele lfirst, llast, rfirst, rlast indic cele dou capete ale subtabelei din stnga si ale
subtabelei din dreapta. Variabilele curent_left si curent_right reprezint elementul curent din stnga
respectiv din dreapta. Temp este tabela temporar folosit pentru sortare.
286
Structuri de date i algoritmi
_______________________________________________________________________________
End;
For index:=lfirst to rlast do
A[index] := Temp[index]
End;
________________________________________________________________________________
287
Structuri de date i algoritmi
_______________________________________________________________________________
Definiia 6.1.: Un arbore binar posed proprietatea de ansamblu dac orice nod al su verific
proprietatea: cheia de cutare a nodului este mai mare sau egal dect cheia de cutare a nodului
fiu_stnga sau dect cheia de cutare a nodului fiu_dreapta.
Definiia 6.2.: Un ansamblu (heap) este un arbore binar complet ce posed proprietatea de
ansamblu (Definiia 6.1).
DATE A, N;
REZULTATE Ansamblu; { Ansamblul construit din tabela nesortat A }
________________________________________________________________________________
288
Structuri de date i algoritmi
_______________________________________________________________________________
SF-PENTRU
SFALGORITM
Pozitia 1 2 3 4 5 6 7 8 9
________________________________________________________________________________
289
Structuri de date i algoritmi
_______________________________________________________________________________
tabela 7 5 8 2 3 9 1 6 4
originala
dupa (b) 7 5 8 6 3 9 1 2 4
dupa (c) 7 5 9 6 3 8 1 2 4
dupa (d) 7 6 9 5 3 8 1 2 4
dupa (e) 9 6 8 5 3 7 1 2 4
Pasul 2: Nodul cu cheia 2 violeaz proprietatea de ansamblu (arborele binar este reprezentat n
Figura VI.8.b.)
- cernem valoarea nodului cu cheia 2;
- interschimbm nodul cu cheia 2 cu nodul cu cheia 9;
- arborele binar este reprezentat n Figura VI.8.d.
Pasul 3: Nodul cu cheia 8 violeaz proprietatea de ansamblu (arborele binar este reprezentat n
Figura VI.8.d.)
- cernem valoarea nodului cu cheia 8;
- interschimbm nodul cu cheia 2 cu nodul cu cheia 6;
- arborele binar este reprezentat n Figura VI.8.c.
Pasul 4: Nodul cu cheia 5 violeaz proprietatea de ansamblu (arborele binar este reprezentat n
Figura VI.8.d.)
- cernem valoarea nodului cu cheia 5;
- interschimbm nodul cu cheia 5 cu nodul cu cheia 6;
- arborele binar este reprezentat n Figura VI.8.e.
Pasul 5: Nodul cu cheia 7 violeaz proprietatea de ansamblu (arborele binar este reprezentat n
Figura VI.8.e.)
- cernem valoarea nodului cu cheia 7;
________________________________________________________________________________
290
Structuri de date i algoritmi
_______________________________________________________________________________
________________________________________________________________________________
291
Structuri de date i algoritmi
_______________________________________________________________________________
DATE A, N;
REZULTATE A; { tabela A sortat n ordine cresctoare }
________________________________________________________________________________
292
Structuri de date i algoritmi
_______________________________________________________________________________
Un arbore binar complet cu N noduri are nevoie de log2(N +1) operaii, n cazul cel mai
nefavorabil, pentru a cerne nodul rdcin, astfel nct s ajung n poziia de nod frunz.
Algoritmul Creare_Ansamblu efectueaz un numr de log2N interschimbri, deci complexitatea sa
va fi O(log2N). [Tom, 1997]
Ciclul PENTRU din algoritmul de sortare se va executa de N-1 ori, deci complexitatea
algoritmului de sortare este O(Nlog2N).
Algoritmul de sortare prin ansambluri are complexitatea O(Nlog2N) n toate din cele trei
cazuri de analizat: cazul general, favorabil i nefavorabil [Knu, 1976].
Pentru tabele mici algoritmul de sortare prin ansambluri este ineficient, dar foarte eficient
pentru cele tabele mari. Nu necesit memorie suplimentar. Eficiena algoritmul de sortare prin
ansambluri nu este afectat de ordinea iniial a elementelor.
Sortarea RADIX (sau sortarea digital ) este o metod de sortare care precede apariia
calculatoarelor electronice, fiind inspirat dintr-o metod de sortare mecanic a cartelelor perforate.
Este una din cele mai eficiente metode de sortare intern, cu condiia ca dimensiunea N a numrului
de nregistrri de sortat s nu fie prea mic, iar cheile dup care se face ordonarea s nu fie prea mici.
Algoritmul de sortare Radix trateaz cheile ca i cum ar fi numere reprezentate ntr-o baz
M, utiliznd cifrele din reprezentarea individuale a numerelor (de exemplu, caracterele pot fi
reprezentate n baz 128).
Dac folosim clasica reprezentare zecimal, deci M = 10, vom folosi 10 buzunare
corespunznd celor 10 cifre zecimale ale sistemului de numeraie zecimal. Fiecare coloan este
sortat ncepnd cu rangul cel mai puin semnificativ al cheilor (primul din dreapta), mutnd
nregistrrile din zona de intrare a algoritmului de sortare ntr-o zon auxiliar a algoritmului de
sortare. Procesul de sortare continu apoi cu urmtorul rang semnificativ, pn cnd, n pasul final
se ordoneaz toate nregistrrile.
________________________________________________________________________________
293
Structuri de date i algoritmi
_______________________________________________________________________________
unei cifre din reprezentarea cheilor de sortat n baza M. Fiecare buzunar poate fi reprezentat ca o
structur de date de tip coad (list FIFO). La sfritul fiecrui pas al procesului de sortare, cozile
pot fi combinate uor n ordine potrivit.
Dac numrul maxim de cifrei ntr-o cheie este M, atunci vor fi necesari M pai de sortare,
pornind de la cifra cea mai puin semnificativ la cifra cea mai semnificativ. Este recomandat a se
folosi reprezentarea nlnuit, sub forma de list simpl nlnuit, a structurii de date
corespunznd buzunarelor, deoarece nu putem ti cte nregistrri vor intra ntr-un buzunar.
Prima dat, vom sorta nregistrrile dup cifra cea mai puin semnificativ a cheii,
interclasm apoi buzunarele. Repetm procesul de la primul pas, sortnd nregistrrile dup cifra
urmtoare, interclasm iari buzunarele, .a.m.d.
________________________________________________________________________________
294
Structuri de date i algoritmi
_______________________________________________________________________________
________________________________________________________________________________
295
Structuri de date i algoritmi
_______________________________________________________________________________
Else
tail[h]^.next := r;
tail[h] := r;
r := r^.next;
End;
r := nil; { interclasm buzunarele }
For j:=9 downto 0 do
If head[j] <> nil then
Begin
tail[j]^.next := r;
r := head[j]
End;
End;
SORTARE_RADIX := r;
End;
BIBLIOGRAFIE
296
Structuri de date i algoritmi
_______________________________________________________________________________
Aho, A. V., J. E. Hopcroft, J. D. Ullman [1974]. The Design and Analysis of Computer
Algorithms, AddisonWesley,Reading,Massachusetts.
Aho, A. V., J. E. Hopcroft, J. D. Ullman [1987]. Data Structures and Algorithms, Addison
Wesley,Reading,Massachusetts.
Andonie, R., I. Grbacea [1995]. Algoritmi fundamentali. O perspectiv C++, Editura Libris,
Cluj-Napoca.
Blaga P., G. Coman, S. Groze [1978]. Bazele Informaticii I. Culegere de probleme, Litografia
Universitii Babe-Bolyai, Cluj-Napoca.
Bhm, C., T. C. Jacopini [1966]. Flow Diagrams, Turing Machines and Languages with only
two Formation Rules, Comm. A.C.M. 9:5.
Boian F., M. Frentiu [1992]. Bazele Informaticii. Limbajul Pascal, ediia a II-a, Litografia
Universitii Babe-Bolyai, Cluj-Napoca.
Cristea, V., I. Athanasiu, E. Kalisz, A. Pnoiu [1992]. Turbo Pascal 6.0, Editura Teora,
Bucureti.
Cristea, V., I. Athanasiu, E. Kalisz, V. Iorga, [1993]. Tehnici de programare, Editura Teora,
Bucureti.
Dale N., S. C. Lilly [1988]. Pascal Plus Data Structures, D. C. Heath and Company, Lexington,
Massachusetts.
Fortune, S., C. J. Van Wyk [1993]. Efficient Exact Arithmetic for Computational Geometry,
Proceedings of the 9th ACM Symposium Computational Geometry.
________________________________________________________________________________
297
Structuri de date i algoritmi
_______________________________________________________________________________
Frentiu M., S. Groze [1986]. Bazele Informaticii, ediia a II-a, Litografia Universitii Babe-
Bolyai, Cluj-Napoca.
Giumale, C.A. [2004]. Introducere n analiza algoritmilor. Teorie i aplicaie, Editura Polirom,
Bucureti.
Horowitz E., S. Sahni [1978]. Fundamentals of Computer Algorithms, Computer Science Press,
Rockville.
Korsh, J. F., L. J.Garrett [1988]. Data Structures, Algorithms and Program Style Using C, PWS-
Kent Publishing Co., Boston.
Lewis, H.R., L. Denenberg [1991]. Data Structures & Their Algorithms, Harper Collins
Publishers, New/York.
Livovschi L., [1980]. Scheme logice. Semnificaie, elaborare, verificare, testare, Editura
Tehnic, Bucureti.
Mocanu, M., G. Marian, C. Bdic, C. Bdic [1993]. 333 probleme de programare, Editura
Teora, Bucureti.
Tomescu, I., [1997]. Data Structures, Editura Universitii din Bucureti, Bucureti.
________________________________________________________________________________
298
Structuri de date i algoritmi
_______________________________________________________________________________
Tudor, S. [1993]. Tehnici de programare i structuri de date, vol. II, Editura Turbo Rabbit,
Bucureti.
________________________________________________________________________________
299