You are on page 1of 13

6.

Arbori de compresie Huffman


n analiza algoritmilor pe care i-am studiat pn acum prioritar a
fost complexitatea timp. n acest capitol ne punem problema elaborrii
unor algoritmi care s micoreze spaiul necesar memorrii unui fiier.
Tehnicile de compresie sunt utile pentru fiiere text, n care
anumite caractere apar cu o frecen mai mare dect altele, pentru
fiiere ce codific imagini sau sunt reprezentri digitale ale sunetelor ori
ale unor semnale analogice, ce pot conine numeroase motie care se
repet. !hiar dac astzi capacitatea dispozitielor de memorare a
crescut foarte mult, algoritmii de compresie a fiierelor rmn foarte
importani, datorit olumului tot mai mare de informaii ce trebuie
stocate. n plus, compresia este deosebit de util n comunicaii,
transmiterea informaiilor fiind mult mai costisitoare dect prelucrarea
lor.
"na dintre cele mai rspndite tehnici de compresie a fiierelor
text, care, n funcie de caracteristicile fiierului ce urmeaz a fi
comprimat, conduce la reducerea spaiului de memorie necesar cu #$%-
&$%, a fost descoperit de '. (uffman n )&*# i poart numele de
codificare (cod) Huffman. n loc de a utiliza un cod n care fiecare
caracter s fie reprezentat pe + sau pe , bii -lungime fix., se utilizeaz
un cod mai scurt pentru caracterele care sunt mai frecente i coduri mai
lungi pentru cele care apar mai rar.
/ presupunem c aem un fiier de )$$.$$$ de caractere din
alfabetul 0a,b,c,d,e,f1, pe care dorim s-l memorm ct mai compact.
'ac am folosi un cod de lungime fix, pentru cele 2 caractere, ar fi
necesari cte 3 bii. 'e exemplu, pentru codul4
a b c d e f
cod fix $$$ $$) $)$ $)) )$$ )$)
ar fi necesari n total 3$$.$$$ bii.
/ presupunem acum c frecenele cu care apar n text cele 2
caractere sunt 4
a b c d e f
frecen56 7* )3 )# )2 & *
!onsidernd urmtorul cod de lungime ariabil 4
a b c d e f
cod ariabil $ )$) )$$ ))) ))$) ))$$
ar fi necesari doar ##7.$$$ bii -deci o reducere a spaiului de memorie
cu aproximati #*%..
218
8roblema se reduce deci la a asocia fiecrui caracter un cod
binar, n funcie de frecen, astfel nct s fie posibil decodificarea
fiierului comprimat, fr ambiguiti. 'e exemplu, dac am fi codificat
a cu )$$) i b cu )$$)$), cnd citim n fiierul comprimat secena )$$)
nu putem decide dac este orba de caracterul a sau de o parte a codului
caracterului b.
9deea de a folosi separatori ntre codurile caracterelor pentru a nu
crea ambiguiti ar conduce la mrirea dimensiunii codificrii.
8entru a eita ambiguitile este necesar ca nici un cod de
caracter s nu fie prefix al unui cod asociat al unui caracter -un astfel de
cod se numete cod prefix..
6.1. Codul Huffman
'. (uffman a elaborat un algoritm :reed; care construiete un
cod prefix optimal, numit cod (uffman. 8rima etap n construcia
codului (uffman este calcularea numrului de apariii ale fiecrui
caracter n text. <xist situaii n care putem utiliza frecenele standard
de apariie a caracterelor, calculate n funcie de limb sau de specificul
textului.
=ie !>0c
1
,c
2
,...,c
n
1 mulimea caracterelor dintr-un text, iar
f
1
,f
2
,...,f
n,
respectiv, num6rul lor de apariii. 'ac l
i
ar fi lungimea
irului ce codific simbolul c
i
, atunci lungimea total a reprezentrii ar fi 4
L l f i i
i
n
=
=

1
/copul nostru este de a construi un cod prefix care s minimizeze
aceast expresie. 8entru aceasta, construim un arbore binar complet n
manier bottom-up astfel 4
-9niial, considerm o partiie a mulimii !>0 0c
1
,f
1
1,0c
2
,f
2
1, ...,
0c
n
,f
n
11, reprezentat printr-o pdure de arbori formai dintr-un singur
nod.
-8entru a obine arborele final, se execut n-) operaii de
unificare.
"nificarea a doi arbori ?
1
i ?
2
const n obinerea unui arbore ?,
al crui subarbore stng este ?
1
, subarbore drept ?
2
, iar frecena
rdcinii lui ? este suma frecenelor rdcinilor celor doi arbori. @a
fiecare pas unificm # arbori ale cror rdcini au frecenele cele mai
mici.
219
'e exemplu, arborele (uffman asociat caracterelor 0a,b,c,d,e,f1
cu frecenele 07*,)3,)#,)2,&,*1 se construiete pornind de la cele cinci
noduri din figura )4

=ig. ).
8as )4 "nific arborii corespunztori lui e i f, deoarece au frecenele
cele mai mici4
=ig. #.
8as #4 "nific arborii corespunztori lui b i c4
=ig. 3.
8as 34 "nific arborele corespunztor lui d i arborele obinut la primul
pas, cu rdcina ce are frecena )74

=ig. 7.
8as 74 "nific arborii ce au frecenele #* i 3$.
=ig. *.
8as *4 "nificnd ultimii doi arbori, obin arborele (uffman asociat
acestui set de caractere cu frecenele specificate iniial.
220
=ig. 2.
Aodurile terminale or conine un caracter i frecena
corespunztoare caracteruluiB nodurile interioare conin suma
frecenelor caracterelor corespunztoare nodurilor terminale din
subarbori.
?rborele (uffman obinut a permite asocierea unei codificri
binare fiecrui caracter. !aracterele fiind frunze n arborele obinut, se a
asocia pentru fiecare deplasare la stnga pe drumul de la rdcin la
nodul terminal corespunztor caracterului un $, iar pentru fiecare
deplasare la dreapta un ).
Cbinem codurile 4
a b c d e f
cod $ )$$ )$) ))$ )))$ ))))
Observaii
- caracterele care apar cel mai frecent sunt mai aproape de
rdcin i astfel lungimea codificrii a aea un numr mai mic de bii.
- la fiecare pas am selectat cele mai mici dou frecene, pentru a
unifica arborii corespunztori. 8entru extragerea eficient a minimului
om folosi un min-heap. ?stfel timpul de execuie pentru operaiile de
extragere minim, inserare i tergere a fi, n cazul cel mai defaorabil,
de O(log n).
Algoritm de construcie a arborelui Huffman
*

8as ). 9niializare 4
- fiecare caracter reprezint un arbore format dintr-un singur nodB
- organizm caracterele ca un min-heap, n funcie de frecenele de
apariieB
*
8rogramul Huffman realizeaz6 compactarea Di decompactarea unui fiDier text
utiliznd arbori (uffman.
221
8as #. /e repet de n-) ori 4
- extrage succesi E i F, dou elemente din heap
- unific arborii E i F 4
- creaz G un nou nod ce a fi rdcina arborelui
- GH.st 4> E
- GH.dr 4> F
- GH.frec 4> EH.frecIFH.frec
- insereaz G n heapB
8as 3. /ingurul nod rmas n heap este rdcina arborelui (uffman. /e
genereaz codurile caracterelor, parcurgnd arborele (uffman.
Analiza complexitii
9niializarea heapului este liniar. 8asul # se repet de n-) ori i
presupune dou operaii de extragere a minimului dintr-un heap i de
inserare a unui element n heap, care au timpul de execuie de C-log n..
'eci complexitatea algoritmului de construcie a arborelui (uffman este
de O(n log n).
Corectitudinea algoritmului
Trebuie s demonstrm c algoritmul lui (uffman produce un
cod prefix optimal.
Lema 1.
=ie x, ; !, dou caractere care au frecena cea mai mic.
?tunci exist un cod prefix optimal n care x i ; au codificri de aceeai
lungime i care difer doar prin ultimul bit.
Demonstraie
=ie T arborele binar asociat unui cod prefix optimal oarecare i
fie a, b dou noduri de pe nielul maxim, care sunt fiii aceluiai nod.
8utem presupune fr a restrnge generalitatea c fJaK fJbK i fJxK
fJ;K. !um x i ; au cele mai mici frecene rezult c fJxK fJaK i fJ;K
fJbK. Transformm arborele T n TL, schimbnd pe a cu x 4
=ig. +.
Aotm cu !-T. costul arborelui T4
C T f c niv c
T
c C
( ) ( ) ( ) =

222
C T C T f x niv x f a niv a f x niv x f a niv a T T T T ( ) ( ') ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ' ' = +
C T C T f a f x niv a niv x
niv a niv x
niv x niv a
T T
T T
T T
( ) ( ') ( ( ) ( )) ( ( ) ( ))
( ) ( ) '
=
=
=
0, pentru c
- . - . L
{
n mod analog, construim arborele T, schimbnd pe x cu ;. Cbinem4
C T C T f b f y niv b niv y T T ( ') ( '') ( ( ) ( )) ( ( ) ( )) = 0.

'eci !-T. !-TLL., dar cum T era optimal deducem c Teste arbore
optimal i n plus x i ; sunt noduri terminale situate pe nielul maxim, fii
ai aceluiai nod.
M.<.'.
Observaie
'in lem deducem c pentru construcia arborelui optimal putem
ncepe prin a selecta dup o strategie :reed; caracterele cu cele mai mici
frecene.
Lema 2.
=ie T un arbore binar complet corespunzator unui cod prefix
optimal pentru alfabetul !. 'ac x i ; sunt dou noduri, fii ai aceluiai
nod z n T, atunci arborele TL obinut prin eliminarea nodurilor x i ; este
arborele binar complet asociat unui cod prefix optimal pentru alfabetul
!L > -!-0x,;1. 0 z1, fJzK fiind fJxKIfJ;K.
Demonstra!ie
niv x niv y niv z
c C x y niv c niv c
f x niv x f y niv y
f x f y niv z f z niv z f x f y
f z niv z f x f y
T T T
T T
T T
T T
T
( ) ( ) ( )
, , ( ) ( )
( ) ( ) ( ) ( )
( ( ) ( )) ( ( ) ) ( ) ( ) ( ) ( )
( ) ( ) ( ( ) ( )).
'
'
= = +
=
+ =
= + + = + + =
= + +
U
V
W
1
1
r o
'eci,
C T f c niv c C T f x f y
c C
T ( ) ( ) ( ) ( ') ( ( ) ( )) = = + +

'ac presupunem prin reducere la absurd c arborele TN nu este


optimal pentru alfabetul !N > -!-{x,;}. {z} T, ale crui frunze
sunt caractere din !N, astfel nct !-T. O !-T..
!um z este nod terminal n T, putem construi un arbore T
1
pentru alfaetul !, at"rn"n# pe $ %i & ca 'i ai lui (.
!()
1
) = !().If-x.If-;. O !-T., ceea ce contrazice ipoteza c T este
arbore optimal pentru !. 'eci, TN este un arbore optimal pentru !N.
M.<.'.
!orectitudinea algoritmului lui (uffman este o consecin5
imediat a celor dou leme.
Observaie
22*
Petoda de compresie bazat pe arbori (uffman statici are o serie
de dezaantaQe4
). =iierul de compactat trebuie parcurs de dou ori4 o dat pentru a
calcula numrul de apariii ale caracterelor n text, a doua oar pentru a
comprima efecti fiierul. 'eci metoda nu poate fi folosit pentru
transmisii de date pentru care nu este posibil reluarea.
#. 8entru o dezarhiare ulterioar a fiierului, aa cum este i firesc, este
necesar memorarea arborelui (uffman utilizat pentru comprimare, ceea
ce conduce la mrirea dimensiunii codului generat.
3. ?rborele (uffman generat este static, metoda nefiind capabil s se
adapteze la ariaii locale ale frecenelor caracterelor.
?ceste dezaantaQe au fost n mare parte eliminate n metodele
care folosesc arbori (uffman dinamici, ideea fiind ca la fiecare nou
codificare, arborele (uffman s se reorganizeze astfel nct caracterul
respecti s aib eentual un cod mai scurt.
6.2. Exerciii
). !onstrui5i arborele (uffman corespunztor alfabetului
!>0a,b,c,d,e,f,g,h1 i frecen5elor4
a b c d e f g h
frecen5
a
* )$ + * , )* 7$ )$
!onstrui5i codul (uffman i ealua5i necesarul de memorie
pentru un fiier cu )$$$$$ de caractere, comparati cu necesarul de
memorie pentru un cod de lungime fix.
# !are este un cod (uffman pentru alfabetul,
!>0a,b,c,d,e,f,g,h,i1 i frecen5ele
a b c d e f g h i
frecen5
a
) ) # 3 * , )3 #) 37
8ute5i generaliza rspunsul pentru cazul n care frecen5ele sunt
primele n numere din irul =ibonacciR
3. 'emonstra5i c un arbore binar care nu este strict nu poate
corespunde unui cod prefix optimal.
7. 'ac presupunem c oricare dou caractere din alfabet au
frecen5e distincte, atunci arborele (uffman este unicR
*. 'emonstra5i c nici o schem de compresie nu poate garanta
reducerea spa5iului de memorie necesar unui fiier de caractere aleatoare
pe , bi5i nici mcar cu un singur bit.
22+
Anex
program Huffman;
uses crt;
const NrMaxNoduri = 256;
type Nod = 1..NrMaxNoduri;
Arbore = ^NodArbore;
NodArbore = record
inf: char;
f: word;
st dr t: Arbore;
end;
!eap = array"Nod# of Arbore;
$ar % nrbiti: byte; n i: Nod;
h: heap;
fisier farh fde&arh: text;
A: Arbore; x y &: Arbore;
t: array"char# of Arbore;
't"c#=pointer spre nodu% ter(ina% ce contine caracteru% c)
fr: array"char# of word;
'frec$ente%e caractere%or in textu% de co(pri(at)
procedure ca%cu%*frec$ente;
$ar c: char;
be+in
assi+n,fisier -t.in-.; reset,fisier.;
whi%e not eof,fisier. do
be+in
read,fisier c.;
inc,fr"c#.
end;
c%ose,fisier.;
end;
procedure /o(b!eap,i n: Nod.;
'co(bina heap0u% cu radacina 2i cu heap0u% cu radacina 2i11 si
cu nodu% i)
$ar parinte fiu: Nod;
$: Arbore;
be+in
$ := h"i#;
parinte := i;
fiu := 22i;
whi%e fiu 3= n do
be+in
if fiu 3 n then
if h"fiu#^.f 4 h"fiu11#^.f then fiu := fiu11;
if $^.f 4 h"fiu#^.f then
be+in
h"parinte# := h"fiu#;
parinte := fiu;
fiu := fiu22;
end
e%se
fiu := n11;
end;
h"parinte# := $;
end;
procedure initia%i&are;
$ar p: Arbore; %: byte; i: Nod;
be+in
n := 1;'nu(aru% efecti$ de caractere din text)
for % := 1 to 255 do
if fr"chr,%.# 34 5 then'acest caracter apare in text)
be+in
new,p.; p^.inf := chr,%.;
p^.f := fr"chr,%.#;
p^.st:=ni%; p^.dr := ni%; p^.t := ni%;
h"n# := p; t"chr,%.# := p;
inc,n.
end;
dec,n.;
'constructie heap)
for i := n di$ 2 downto 1 do /o(b!eap,i n.;
write,- !eap0u% este: -.;
for i := 1 to n do
write,h"i#^.f - -.;
write%n;
end;
function extra+e*(in:Arbore;
'functia extra+e din heap ce% (ai (ic e%e(ent)
be+in
extra+e*(in := h"1#;
h"1# := h"n#;
dec,n.;
/o(b!eap,1 n.;
end;
procedure insert,x: Arbore.;'inserea&a in heap arbore%e x)
$ar fiu parinte: Nod;
be+in
inc,n.; h"n# := x;
fiu := n; parinte := n di$ 2;
whi%e ,parinte 4 5. and ,h"parinte#^.f 4 x^.f. do
be+in
h"fiu# := h"parinte#;
fiu := parinte;
parinte := parinte di$ 2
end;
h"fiu# := x
end;
procedure /odificare;
'preia fiecare caracter din fisieru% sursa si i% codifica;
fiecare octet obtinut este p%asat in fisieru% arhi$a)
$ar $: byte; c: char;
procedure codifica,c: char.;
'codifica caracteru% c)
$ar p: Arbore;
d: array"Nod# of 5..1;
i 6: Nod;
be+in
i := 1;
p := t"c#; 'nodu% ter(ina% corespun&ator %ui c)
whi%e p^.t 34 ni% do
be+in 'obtin in d codu% %ui c in ordine in$ersa)
if p = p^.t^.st then 'p este fiu stan+)
d"i# := 5
e%se 'p este fiu drept)
d"i# := 1;
inc,i.;
p := p^.t
end;
for 6 := i01 downto 1 do
be+in
$ := $ sh% 1 1d"6#;
inc,nrbiti.;
if nrbiti = 7 then
be+in'cand co(p%eta( un octet scrie( caracteru%
corespun&ator in arhi$a)
write,farh chr,$..;
nrbiti := 5; $ := 5;
end;
end;
end;
be+in 'procedura de codificare a fisieru%ui sursa)
assi+n,farh -testArh.in-.; rewrite,farh.; reset,fisier.;
nrbiti := 5;'nu(aru% de biti din octetu% curent)
$ := 5;'$a%oarea octetu%ui curent)
whi%e not eof,fisier. do
be+in
read,fisier c.;
codifica,c.;
end;
if nrbiti 34 5 then
be+in 'u%ti(u% octet inco(p%et trebuie trecut in arhi$a)
$ := $ sh% ,70nrbiti.;
write,farh chr,$..;'
nrbiti $a indica nu(aru% de biti ce trebuie extrasi din
u%ti(u% octet)
end;
c%ose,fisier.; c%ose,farh.;
end;
procedure 8ecodificare;
'preia din fisieru% fiecare octet si extra+e fiecare bit
dep%asandu0se corespun&ator in arbore%e !uff(an)
$ar c: char; p: Arbore;
procedure decodifica,c: char; sf: boo%ean.;
'extra+e bitii din octetu% corespun&ator caracteru%ui c)
$ar i nr: byte;
be+in
if sf then nr := nrbiti'u%ti(u% octet a$ea doar nrbiti)
e%se nr := 7;
for i := 1 to nr do
be+in 'extra+e( pe rand cei 7 biti din caracteru% c)
if ,ord,c. shr ,70i.. and 1 = 5 'bit0u% i) then
p := p^.st
e%se
p := p^.dr;
if p^.st = ni% then
be+in 'p ter(ina% a( decodificat un caracter)
write,fde&arh p^.inf.;
p := A;
end;
end;
end;
be+in 'procedura de decodificare a fisieru%ui arhi$a)
p := A; 'indica po&itia curenta in arbore%e !uff(an)
reset,farh.; assi+n,fde&arh -h.out-.; rewrite,fde&arh.;
whi%e not eof,farh. do
be+in
read,farh c.;
decodifica,c eof,farh..;
end;
c%ose,farh.; c%ose,fde&arh.;
end;
be+in'pro+ra( principa%)
c%rscr;
ca%cu%*frec$ente;
' constructia arbore%ui !uff(an)
initia%i&are;
for i := 1 to n01 do
be+in
x := extra+e*(in;
y := extra+e*(in;
'unifica arborii x si y)
new,&.; &^.f : =x^.f1y^.f; &^.t := ni%;
&^.st := x; x^.t := &; &^.dr := y; y^.t := &;
insert,&.;
end;
A := h"1#;
/odificare;
8ecodificare;
end.

You might also like