Você está na página 1de 33

Algoritmo de Huffman

Cdigo de Huffman

Algoritmo para a compresso de arquivos, principalmente arquivos textos Atribui cdigos menores para smbolos mais freqentes e cdigos maiores para smbolos menos freqentes Cdigo um conjunto de bits

Cdigo de Huffman

Representao dos dados feita com cdigos de tamanho varivel


Cdigo ASCII A=01000001 B=01000010
. . .

Cdigo de Huffman A=? (0) B=? (110)


. . .

a=01100001 b=01100010

a=? (1111110) b=? (11111111110)

Exemplo

Supondo A e C mais freqentes que C e D no conjunto de valores possveis ABACDA= 0 110 A B

Smbolo A B C D

Cdigo 0 110 10 111

0 10 111 A C D

0 A

Requisito

O cdigo de um smbolo no pode ser prefixo de um outro cdigo

Se isso acontece, tem-se ambigidade na decodificao


Smbolo Huffman

Ex: ACBA = 01010 Os dois bits em vermelho so A e C ou B? Veja que o cdigo de A prefixo do cdigo de B

A B C

0 01 1

Problema

Dada uma tabela de freqncias como determinar o melhor conjunto de cdigos, ou seja, o conjunto que comprimir mais os smbolos? Huffman desenvolveu um algoritmo para isso e mostrou que o conjunto de smbolos obtidos o melhor para conjuntos de dados que tm a freqncia de seus smbolos igual a tabela de freqncia usada

Informaes de frequncia

Algoritmo de Huffman produz tabela de cdigos baseada em informaes de freqncia Dependncia do tipo de dado primrio

O algoritmo em si

Dado: Tabela de freqncias dos N smbolos de um alfabeto Objetivo: Atribuir cdigos aos smbolos de modo que os mais freqentes tenham cdigos menores (menos bits)

O processo de compresso
Huffman A-0.2 B-0.1 a-0.1
. . .

A-0 B-10 a-110


. . .

Fdjoiasdjfoidsjfoisofnsdo Sdjfoisdjfoisdfoisdfoid Oidsfoisdnfosdf Sdoifsjfsdfskodnfsdknf

Arquivo comprimido

Idia bsica

Construir uma rvore binria tal que


A) suas folhas sejam os N smbolos do alfabeto B)cada ramo da rvore seja um valor 1 (esquerda) ou 0 (direita)

Isso uma conveno, o contrrio tambm funciona

O cdigo de um smbolo ser a seqncia de bits dos ramos da raiz at sua posio na rvore

Exemplo
Smbolo A B C D Cdigo 0 110 10 111

Exemplo
Smbolo A B C D E F G H I Freq. 25 20 15 15 10 8 8 4 4

Exemplo
Smbolo A B C D E F G H I Freq. 25 20 15 15 10 8 8 4 4 Cdigo 01 00 101 100 1111 1101 1100 11101 11100

Codificando
a b c a 01100001 01100010 01100011 01100001 a 1 0 b 2 10 c 3 11 010110

Decodificando
010110 a b c a

A rvore no algoritmo de Huffman


rvore de tamanho fixo (2N-1 ns) Logo sua representao pode ser seqencial (em um array) ao invs de dinmica Construo da rvore das folhas para a raiz, ento os ponteiros sero: filhopai Os ns no tm os campos filhoEsquerda e filhoDireita

Os ns da rvore

Cada n tem 4 campos:

Father ponteiro para a posio do pai do n isLeft (para que este campo?)

True se o n filho esquerda False se o n filho direita

symbol o smbolo representado pelo n freq a freqncia do smbolo

Processo

rvore construda botton-up, a partir dos 2 smbolos de menor freqncia e, recursivamente tomando-se sempre as 2 sub-rvores menos freqentes Definio: A freqncia de uma subrvore a soma das freqncias de seus 2 filhos

Processo

Cria-se um n (n folha) para cada smbolo da tabela de freqncia Cria-se um vetor que aponta para cada um desses ns Insere-se tambm esses ns em uma uma fila de prioridades (os ns menos freqentes primeiro)

Notem: temos uma rvore E uma fila de prioridades A rvore ns estamos construindo A fila de prioridades ns usamos para construir a rvore

O processo termina quando todos os ns da fila de prioridades forem eliminados

Os ltimos dois juntam-se e formam a raiz da rvore

Processo(viso geral)

Enquanto existir mais de 1 n na fila


Retiram-se os dois primeiros Gera-se um novo n a partir destes Insere estes dois na rvore

No final restar um n na fila de prioridades

N-n smbolos tratados Frequencias uma tabela com os smbolos e suas freqncias Code Sada do algoritmo. Uma tabela com os smbolos e os seus respectivos cdigos Rootnodes fila de prioridades Position vetor de ponteiros para os ns iniciais (ns folhas)

Code Huffman(N,Frequencias) rootnodes=FilaVazia //inicializa o conjunto de root nodes for(i=0;i<n;i++){ P=makeNode(frequencias[i]); position[i]=P; //P ponteiro para folha

pqinsert(rootnods,P);
} //este for cria todos os ns folhas ...continua no prximo slide

remQueueElem retorna o primeiro elemento da fila de prioridades makeNode gera um novo n da rvore Setleft(P,P1) seta o pai de P1 e seta que P1 filho esquerdo Setright(P,P2) seta o pai de P2 e seta que P2 pe filho direito addQueueElem insere um n na fila de prioridades

//gerao da rvore while(size(rootnodes) > 1) { P1=remQueueElem(rootnodes); P2=remQueueElem (rootnodes); //combina P1 e P2 em um n P=makeNode(info(P1)+info(P2)) setleft(P,P1); setRight(P,P2); setQueueElem(rootnodes,P); //n pai na fila de prioridades
}//este while contri a rvore Continua....

//gerando os cdigos a partir da rvore root=remQueueElem (rootnodes); for (i=0; i<n; i++) { P=position[i]; //i-esimo smbolo code[i]=; //string de bits nula while(P!=root) { //sobe na rvore if (isleft(P)) code[i]=0 + code[i]; else code[i]=1+code[i]; P=father(P); } //end while }//end for Fim do algoritmo de Huffman

Algoritmo de Huffman Gera os ns iniciais e Constri a fila de prioridades Gera a rvore binria Gera os cdigos a partir da rvore

A tabela de cdigos (code)


a b c 1 2 3 0 10 11

Exemplo do algoritmo
A B C D E F G H I 25 20 15 15 10 8 8 4 4 01 00 101 100 1111 1101 1100 11101 11100

Tabela de cdigos
Smbolo
A B C D E F G

N bits
2 2 3 3 4 4 4

Cdigo
01 00 101 100 1111 1101 1100

H I

5 5

11101 11100

Codificando
a b c a 01100001 01100010 01100011 01100001 a 1 0 b 2 10 c 3 11 010110

Decodificando
010110 a b c a

Operadores bit a bit no C


& | ^ >> << AND OR OR exclusivo (XOR) Deslocamento direita Deslocamento esquerda

Operam sobre char e int

AND bit a bit


AND bit a bit 11000001 01111111 &----------------01000001
void main(void) { char a,b,c; a=193; b=127; c=a & b;//c=65 printf(%i\n,c); };

OR bit a bit
void main(void) {

OR bit a bit 11000001 01111111 |----------------11111111


};

char a,b,c; a=193; b=127; c=a & b;//c=255 printf(%i\n,c);

XOR bit a bit


XOR bit a bit 11000001 01111111 ^----------------10111110
void main(void) { char a,b,c; a=193; b=127; c=a & b;//c=190 printf(%i\n,c); };

Deslocamento direita e esquerda


void main(void) { char x; x<<1; x<<3; x<<2;

X=7

0000 0111

7 14 112 192 96 24

X<<1 0000 1110 X<<3 0111 0000 X<<2 1100 0000 X>>1 0110 0000 X>>2 0001 1000

x>>1;
x>>2; };