Estrutura de Dados

Transcrição

Estrutura de Dados
Estruturas de Dados
e
Técnicas de Programação
c 2010-2011 Tomasz Kowaltowski
Copyright Instituto de Computação
Universidade Estadual de Campinas
Algumas transparências foram adaptadas da apostila Estruturas de Dados
e Técnicas de Programação de autoria de Cláudio L. Lucchesi e Tomasz
Kowaltowski.
Tomasz Kowaltowski
Instituto de Computação
Universidade Estadual de Campinas
Estas transparências somente podem ser copiadas para uso pessoal dos
docentes e alunos das disciplinas oferecidas pelo Instituto de Computação
da UNICAMP.
www.ic.unicamp.br/∼tomasz
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
1
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
2
Pré-requisito e objetivos
Introdução
I
Pré-requisito: curso básico de programação em C
I
Objetivos:
I
I
I
Programação em (relativamente) baixo nı́vel
Técnicas de programação e estruturação de dados
Preparação para:
I
I
I
I
I
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Introdução
3
Análise de algoritmos
Programação de sistemas
Programação em geral
Bancos de dados
Engenharia de software
...
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Introdução
4
Programa
I
I
I
I
I
I
I
I
I
I
I
I
I
I
Introdução à análise de algoritmos
Estruturação elementar de dados: matrizes, registros, apontadores
Estruturas lineares: pilhas, filas, filas duplas
Recursão e retrocesso
Árvores binárias: representação, percursos
Árvores gerais: representação, percursos
Aplicação de árvores:
árvores de busca (AVL), filas de prioridade,
árvores B, árvores rubro-negras, árvores digitais
Listas generalizadas
Espalhamento
Processamento de cadeias de caracteres
Gerenciamento de memória
Algoritmos de ordenação
Algoritmos em grafos
Tipos abstratos de dados e orientação a objetos
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Introdução
Bibliografia
5
Bibliografia
6
G. H. Gonnet.
Handbook of Algorithms and Data Structures.
Addison-Wesley, 1984.
A. V. Aho, J. E. Hopcroft, and J. Ullman.
Data Structures and Algorithms.
Addison-Wesley, 1983.
E. Horowitz and S. Sahni.
Fundamentals of Data Structures in Pascal.
Computer Science Press, 1984.
A. Drozdek.
Estrutura de Dados e Algoritmos em C++.
Thomson, 2002.
D. E. Knuth.
The Art of Computer Programming, volume I: Fundamental
Algorithms.
Addison-Wesley, 1978.
J. L. Szwarcfiter e L. Markenzon.
Estruturas de Dados e seus Algoritmos.
LTC Editora, 1994.
C. L. Lucchesi e T. Kowaltowski.
Estruturas de Dados e Técnicas de Programação.
Instituto de Computação – UNICAMP, 2003.
E. M. Reingold and W. J. Hanson.
Data Structures.
Little Brown and Company, 1983.
P. Feofiloff.
Algoritmos em Linguagem C.
Elsevier Editora Ltda., 2009.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
R. Sedgewick.
Algorithms in C.
Addison-Wesley, 1990.
Bibliografia
7
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Bibliografia
8
D. F. Stubbs and N. W. Webre.
Data Structures with Abstract Data Types and Pascal.
Brooks/Cole, 1985.
A. M. Tenenbaum, Y. Langsam, and M. J. Augenstein.
Data Structures using C.
Prentice-Hall, 1990.
Noções de Análise de Algoritmos
N. Wirth.
Algorithms + Data Structures = Programs.
Prentice-Hall, 1976.
N. Ziviani.
Projeto de Algoritmos (2a. ed.)
Thomson, 2004.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Bibliografia
9
Escolha da estrutura
(a)
Noções de Análise de Algoritmos
10
Exemplo de análise de trechos de programas
Importância da escolha de estrutura de dados – busca do k-ésimo
elemento numa seqüência:
...
x = a[k];
...
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
...
p = a;
i = 0;
w h i l e ( i <k ) {
p = p−>p r o x ;
i ++;
}
x = p−>i n f o ;
...
...
f o r ( i =0; i <n ; i ++)
x = a+b ;
...
(a)
(b)
análise simples (1)
análise detalhada (2)
(b)
...
f o r ( i =0; i <n ; i ++)
f o r ( j =0; j <n ; j ++)
x = a+b ;
...
(c)
a
1
2
b
n
5n + 2
c
n2
5n2 + 5n + 2
(1): atribuições (2): atribuições, operações aritméticas e comparações
(a) Número de operações constante (vetor).
(b) Número de operações proporcional a k (lista ligada).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
...
x = a+b ;
...
Noções de Análise de Algoritmos
As duas análises produzem resultados proporcionais para valores crescentes
de n.
11
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Noções de Análise de Algoritmos
12
Notação O()
Exemplo de análise de um procedimento de ordenação
Definição:
f (n) = O(g(n)) se existem n0 e k com f (n) ≤ k ∗ g(n) para todo n > n0 .
Exemplos:
c = O(1)
para qualquer constante c
2 = O(1)
5n + 2 = O(n)
5n2 + 5n + 2 = O(n2 )
O número de comparações de elementos de v, para cada valor de i, é
n − i − 1. O número total de comparações será:
n2 = O(n3 )
nk = O(nk+1 ),
loga n = O(logb n),
v o i d Ordena ( i n t v [ ] , i n t n ) {
i n t i , k , m, t ;
f o r ( i =0; i <n −1; i ++) {
m = i;
f o r ( k=i +1; k<n ; k++)
i f ( v [ k]< v [m] ) m = k ;
t = v [ i ] ; v [ i ] = v [m ] ; v [m] = t ;
}
} /∗ Ordena ∗/
k≥0
n−2
X
a, b > 0
(n − i − 1) =
log2 n = O(log10 n)
i=0
ou seja, o número de comparações é da ordem de O(n2 ).
Outras notações importantes: Θ(), Ω(), etc.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Noções de Análise de Algoritmos
13
Crescimento de algumas funções
n log2 n
1
0
2
1
4
2
8
3
16
4
32
5
64
6
128
7
n log2 n
0
2
8
24
64
160
384
896
n2
1
4
16
64
256
1.024
4.096
16.384
n2 n
+
2
2
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Noções de Análise de Algoritmos
14
Exemplo
n3
1
8
64
512
4.096
32.768
262.144
2.097.152
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
2n
2
4
16
256
65.536
4.294.967.296
≈ 18×1018
≈ 34×1037
Noções de Análise de Algoritmos
Suponha duas máquinas M1 e M2 , sendo a primeira cem vezes mais
rápida do que a segunda. Ambas as máquinas executam um algoritmo de
busca num vetor ordenado de comprimento n. A máquina M1 executa o
algoritmo de busca sequencial (pior caso: n operações); a máquina M2
executa o algoritmo de busca binária (pior caso: log2 n operações).
A seguinte tabela poderia ser obtida através de medidas experimentais de
tempo de execução para vetores de diversos tamanhos, usando alguma
unidade de tempo conveniente.
15
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Noções de Análise de Algoritmos
16
Exemplo (cont.)
n
M1 (rápida)
M2 (lenta)
16
32
64
128
256
512
1024
2048
...
220
221
...
230
16
32
64
128
256
512
1024
2048
...
1.048.576
2.097.152
...
1.073.741.824
400
500
600
700
800
900
1000
1100
...
2000
2100
...
3000
Execução de programas
Supondo que a unidade seja 1µs (microssegundo), 2.097.152µs corresponde a 17
minutos e 1.073.741.824µs equivale a cerca de 12 horas.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Noções de Análise de Algoritmos
17
Exemplo de funções simples
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Execução de programas
18
Exemplo de funções com alocação dinâmica
void g ( i n t x , i n t ∗y ) {
∗y = x ;
} /∗ g ∗/
i n t main ( ) {
int i ;
char c ;
char v [ 5 ] ;
f (& i ) ;
return 0;
} /∗ main ∗/
void f ( i n t ∗z ) {
int y ;
char b ;
y = 235;
g(y , z );
} /∗ f ∗/
typedef char Cadeia [ 5 ] ;
t y p e d e f C a d e i a ∗ ApCadeia ;
typedef struct {
C a d e i a nome ;
int idade ;
} Reg , ∗ApReg ;
v o i d A l o c a ( ApCadeia ∗ c , ApReg ∗ r ) {
api = malloc ( sizeof ( int ) ) ;
∗ api = 10;
∗c = malloc ( s i z e o f ( Cadeia ) ) ;
∗ r = m a l l o c ( s i z e o f ( Reg ) ) ;
} /∗ A l o c a ∗/
ApCadeia apc ;
ApReg a p r ;
int ∗ api ;
i n t main ( ) {
A l o c a (&apc ,& a p r ) ; f r e e ( apc ) ;
f r e e ( apr ) ; f r e e ( api ) ;
return 0;
} /∗ main ∗/
Pilha de execução (supõe inteiros de dois bytes):
apc
i
c
v
y
z
235
b
235
main
f
apr
c
api
r
y
x
global
235
main
Aloca
pilha de execução
g
10
Obs.: Na realidade, os inteiros são armazenados sob a forma binária.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Execução de programas
memória dinâmica
19
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Execução de programas
20
Exemplo de função recursiva
i n t main ( ) {
i n t m;
m = fat (4);
return 0;
} /∗ main ∗/
int fat ( int n) {
i f ( n==0)
return 1;
else
r e t u r n n∗ f a t ( n −1);
} /∗ f a t ∗/
m
res
n
res
n
res
n
res
n
res
n
24
24
4
6
3
2
2
1
1
1
0
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Execução de programas
Estruturas ligadas
21
Listas ligadas simples
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
22
Inserção e remoção com passagem por valor
p
...
...
Declarações (equivalentes):
typedef
struct RegLista ∗ Lista ;
typedef
struct RegLista {
T info ;
L i s t a prox ;
} RegLista ;
p
typedef
struct RegLista {
T info ;
struct RegLista ∗ prox ;
} RegLista , ∗ L i s t a ;
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
23
...
x
void I n s e r e ( L i s t a p , T x ) {
Lista q =
malloc ( sizeof ( RegLista ) ) ;
q−>i n f o = x ;
q−>p r o x = p−>p r o x ;
p−>p r o x = q ;
}
q
v o i d Remove ( L i s t a p , T ∗ x ) {
L i s t a q = p−>p r o x ;
∗ x = q−>i n f o ;
p−>p r o x = q−>p r o x ;
free (q );
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
24
Inserção e remoção com passagem por valor (cont.)
Inserção e remoção com passagem por referência
...
...
...
x
p
p
...
x
q
q
I
O argumento p é o apontador para o predecessor do nó a ser inserido
ou removido.
I
A função ’Remove’ não pode remover um nó que é o único da lista.
I
A função ’Insere’ não pode inserir um nó no inı́cio da lista, inclusive
se ela for vazia.
v o i d I n s e r e ( L i s t a ∗p , T x ) {
Lista q =
malloc ( sizeof ( RegLista ) ) ;
q−>i n f o = x ;
q−>p r o x = ∗p ;
∗p = q ;
}
v o i d Remove ( L i s t a ∗p , T ∗ x ) {
L i s t a q = ∗p ;
∗ x = q−>i n f o ;
∗p = q−>p r o x ;
free (q );
}
Esta convenção elimina os problemas da passagem por valor. Note-se que
as variáveis p e q têm tipos diferentes.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
25
Lista simples com nó cabeça
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
26
Estruturas ligadas
28
Lista simples circular
p
...
p
...
Lista vazia:
p
Problema: lista vazia?
Esta convenção permite o uso de passagem por valor nas funções básicas.
O campo de informação do nó cabeça pode ser aproveitado para guardar
alguma informação adicional (por exemplo, o comprimento da lista).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
27
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Lista circular com nó cabeça
Busca em lista circular com nó cabeça – sentinelas
Lista BuscaCircular (
Lista p , T x) {
/∗ Busca sem s e n t i n e l a ∗/
Lista q = p;
do {
q = q−>p r o x ;
} w h i l e ( ( q!=p ) &&
( q−>i n f o != x ) ) ;
i f ( q==p )
r e t u r n NULL ;
else
return q ;
}
p
...
Lista vazia:
p
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
29
Lista duplamente ligada com nó cabeça
Lista BuscaCircular (
Lista p , T x) {
/∗ Busca com s e n t i n e l a ∗/
Lista q = p;
q−>i n f o = x ;
do {
q = q−>p r o x ;
} w h i l e ( q−>i n f o != x ) ;
i f ( q==p )
r e t u r n NULL ;
else
return q ;
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
30
Operações sobre listas duplamente ligadas
typedef
struct RegListaDupla {
T info ;
s t r u c t R e g L i s t a D u p l a ∗ esq , ∗ d i r ;
} RegListaDupla , ∗ ListaDupla ;
p
...
Lista vazia:
void InsereDuplaEsq (
ListaDupla p , T x) {
ListaDupla q =
malloc ( s i z e o f ( RegListaDupla ) ) ;
q−>i n f o = x ;
q−>e s q = p−>e s q ;
q−>d i r = p ;
p−>esq−>d i r = q ;
p−>e s q = q ;
}
p
I
É possı́vel percorrer os elementos nas duas direções, a partir de
qualquer lugar da lista.
I
É possı́vel remover o elemento apontado.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
v o i d RemoveDupla (
ListaDupla p , T ∗x ) {
p−>esq−>d i r = p−>d i r ;
p−>d i r −>e s q = p−>e s q ;
∗ x = p−>i n f o ;
free (p );
}
A função ’RemoveDupla’ supõe que há pelo menos um elemento na lista.
Estruturas ligadas
31
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
32
Exemplo: operações com polinômios
Exemplo de função: impressão
Seja um polinômio de grau n:
P (x) = an xn + an−1 xn−1 + . . . + a1 x1 + a0 x0
t y p e d e f s t r u c t AuxPol {
int
expo ;
float
coef ;
s t r u c t AuxPol ∗ p r o x ;
} Termo , ∗ P o l i n o m i o ;
onde an 6= 0, exceto possivelmente no caso n = 0.
Representação ligada omite os termos não nulos. Por exemplo, os
polinômios:
P1 (x) = 5x20 − 3x5 + 7
e
P2 (x) = 0:
podem ser representados por:
p1
-1
5
p2
20
-3
5
7
0
void ImprimePolinomio ( Polinomio p) {
i f ( p−>p r o x==p ) {
p r i n t f ( ” P o l i n ô m i o n u l o \n” ) ;
return ;
}
p = p−>p r o x ;
w h i l e ( p−>expo !=−1) {
p r i n t f ( ”(%2d , % 5 . 1 f ) ” ,
p−>expo , p−>c o e f ) ;
p = p−>p r o x ;
}
p r i n t f ( ” \n” ) ;
}
-1
Por convenção, o expoente do nó cabeça é -1.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
33
Soma de polinômios: paradigma de intercalação
-1
q
-1
Exemplo:
qq
50
10
0
−30
...
rr
rr0
-1
34
Matrizes esparsas
...
qq0
r
Estruturas ligadas
pp
pp0
p
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
...
As variáveis pp e qq representam os termos correntes dos polinômios
dentro da malha de repetição e a variável rr aponta para o último termo já
calculado da soma; pp0, qq0 e rr0 são os valores iniciais das variáveis pp,
qq e rr.
A implementação das operações é um exercı́cio. Note-se que o produto de
dois polinômios pode ser calculado como uma sequência de somas de
produtos de um polinômio por um termo.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
35
0
0
0
20
0
0
0 −60
0
0
0
5
Dada uma matriz n × n, quando o número de elementos não nulos é uma
percentagem pequena de n2 (não é o caso do exemplo!), pode ser
conveniente representar a matriz por meio de uma estrutura de listas
ortogonais.
Suporemos, neste exemplo, que as linhas e as colunas são numeradas a
partir de 1.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
36
Matrizes esparsas: listas ortogonais
Operações sobre matrizes esparsas
Alguns exemplos:
-1
1
-1
-1
-1
1
1
-1
2
-1
3
-1
4
typedef
s t r u c t RegEsparsa {
int linha , coluna ;
d o u bl e v a l o r ;
s t r u c t RegEsparsa ∗ d i r e i t a , ∗ abaixo ;
} RegEsparsa , ∗ Matriz ;
1
50
2
-1
2
1
2
3
10
3
-1
4
-1
4
1
50
10
0
−30
20
4
-30
3
4
-60
0
0
0
0
0
20
0
−60
v o i d I n i c i a l i z a M a t r i z ( M a t r i z ∗a , i n t m, i n t n ) ;
void LiberaMatriz ( Matriz a ) ;
d o ub l e E l e m e n t o M a t r i z ( M a t r i z a , i n t i , i n t j ) ;
v o i d A t r i b u i M a t r i z ( M a t r i z a , i n t i , i n t j , do ubl e x ) ;
void SomaMatrizes ( Matriz a , Matriz b , Matriz ∗c ) ;
void M u l t i p l i c a M a t r i z e s ( Matriz a , Matriz b , Matriz ∗c ) ;
4
5
O acesso à matriz é feito a partir do nó cabeça das listas das cabeças das
linhas e das colunas (super-cabeça!).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
0
0
0
5
Estruturas ligadas
37
É importante notar os casos em que a passagem do argumento do tipo
’Matriz’ é feita por referência. (Nas duas últimas operações, a variável ’c’
recebe o resultado.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas ligadas
38
Estruturas lineares em geral: operações tı́picas
Estruturas lineares
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas lineares
39
I
selecionar e modificar o k-ésimo elemento;
I
inserir um novo elemento entre as posições k e k + 1;
I
remover o k-ésimo elemento;
I
concatenar duas sequências;
I
desdobrar uma sequência;
I
copiar uma sequência;
I
determinar o tamanho de uma sequência;
I
buscar um elemento que satisfaz uma propriedade;
I
ordenar uma sequência;
I
aplicar um procedimento a todos os elementos de uma sequência;
I
...
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas lineares
40
Estruturas lineares particulares
Pilha: implementação sequencial
empilha (insere)
0
...
I
...
Pilha (stack): inserção e remoção na mesma extremidade da estrutura
desempilha (remove)
I
topo
Fila (queue): inserção numa extremidade (fim) e remoção na outra
extremidade (inı́cio)
Pilha vazia:
I
Fila dupla (double ended queue): inserção e remoção em ambas
extremidades da estrutura
0
...
topo
(-1)
Inicialmente: topo=-1.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas lineares
41
Pilha: implementação sequencial (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas lineares
42
Estruturas lineares
44
Pilha: implementação ligada
empilha (insere)
0
...
...
topo
...
desempilha (remove)
topo
Pilha vazia:
typedef
struct {
i n t topo ;
T e l e m e n t o s [TAM MAX ] ;
} Pilha ;
v o i d E m p i l h a ( P i l h a ∗p , T x ) {
i f ( ( ∗ p ) . t o p o==(TAM MAX−1))
TrataErro (” Pilha cheia ” ) ;
( ∗ p ) . t o p o++;
((∗ p ) . elementos ) [ ( ∗ p ) . topo ] = x ;
}
topo
(Uma lista ligada simples.)
Exercı́cio: a função “Desempilha”.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas lineares
43
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Pilha: implementação ligada (cont.)
Fila: implementação sequencial
remove
...
...
...
insere
topo
...
frente
typedef struct ElemPilha {
T info ;
struct
ElemPilha ∗ prox ;
} ElemPilha , ∗ P i l h a ;
v o i d E m p i l h a ( P i l h a ∗p , T x ) {
Pilha q =
malloc ( s i z e o f ( ElemPilha ) ) ;
i f ( q==NULL)
T r a t a E r r o ( ” F a l t a memória ” ) ;
q−>i n f o = x ;
q−Prox = ∗p ;
∗p = q ;
}
fim
Convenção: frente precede o primeiro elemento da fila; consequentemente,
o tamanho da fila é dado por fim−frente.
Fila vazia:
... ...
frente
fim
Condição de fila vazia: frente == fim.
Inicialmente: frente = fim = −1.
Exercı́cio: a função “Desempilha”.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas lineares
45
Fila: implementação ligada circular
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
n-1
0
1
2
3
fim
...
..
.
...
Fila vazia:
fila
frente
.
..
fim
frente
fim
Convenção: frente precede o primeiro elemento da fila; consequentemente,
o tamanho da fila é dado por (fim−frente + n)%n.
A fila pode ser representada por uma única variável (fila) ou um par de
variáveis (frente e fim).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
46
Fila: implementação sequencial circular
fila
frente
Estruturas lineares
Estruturas lineares
47
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas lineares
48
Fila: implementação sequencial circular (cont.)
n-1 0
1
2
3
n-1 0 1
2
#d e f i n e TAM MAX FILA 1000
...
...
Fila: implementação sequencial circular (cont.)
typedef struct {
i n t frente , fim ;
T e l e m e n t o s [ TAM MAX FILA ] ;
} Fila ;
.
..
3
...
frente
...
frente
..
fim
fim
Condições:
I
I
I
I
I
Inicial: frente == fim == 0 (ou qualquer outro valor)
Fila vazia: frente == fim
Fila cheia: frente == fim (a mesma condição!)
Solução 1: sacrificar uma posição do vetor; a condição de fila cheia
fica: frente == (fim + 1)%n.
Solução 2: uma variável adicional inteira com o tamanho da fila ou
booleana indicando se a fila está vazia.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas lineares
49
void I n s e r e F i l a ( F i l a ∗f , T x ) {
i f ( ( ∗ f ) . f r e n t e ==(((∗ f ) . f i m+1)%TAM MAX FILA ) )
TrataErro (” F i l a cheia ” ) ;
( ∗ f ) . f i m = ( ( ∗ f ) . f i m+1)%TAM MAX FILA ;
(∗ f ) . elementos [ ( ∗ f ) . fim ] = x ;
}
Exercı́cio: a função “RemoveFila”.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Estruturas lineares
50
Aplicações de pilhas
I
Processamento de linguagens parentéticas:
I
Aplicações de pilhas
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Aplicações de pilhas
I
51
linguagens de programação
XML
I
Implementação da recursão
I
Percurso de estruturas hierárquicas (árvores)
I
Avaliação expressões em notação pós-fixa (notação polonesa reversa)
I
Transformação entre notações
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Aplicações de pilhas
52
Exemplo de aplicação simples: balanceamento de parênteses
Correto
()
[()]
[]()[()[]]
((([[[]]])))
Pilha
Vazia
(
([
([(
([([
([(
([([
([([(
([([
([(
([
(
Vazia
Incorreto
(
)
[)
()()[
)(
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Balanceamento de parênteses (cont.)
Aplicações de pilhas
53
Notações para expressões aritméticas
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Infixa:
I
I
I
Notação pós-fixa:
um operador unário precede o operando
um operador binário separa os dois operandos
parênteses indicam prioridades
I
Pós-fixa: os operadores seguem os operandos
I
Pré-fixa: os operadores precedem os operandos
pós-fixa
a
ab+
abc ∗ +
ab + c∗
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
54
(3 + 5) ∗ 2 − (10 − 3)/2
3 5 + 2 ∗ 10 3 − 2/−
Estados consecutivos da pilha:
Pilha
Vazia
3
3 5
8
8 2
16
16 10
16 10 3
16 7
16 7 2
16 3
13
Exemplos:
infixa
a
a+b
a+b∗c
(a + b) ∗ c
Aplicações de pilhas
Exemplo: avaliação de expressões sob forma pós-fixa
Notação infixa:
I
Resto da sequência
([([][()])])
[([][()])])
([][()])])
[][()])])
][()])])
[()])])
()])])
)])])
])])
)])
])
)
pré-fixa
a
+ab
+a ∗ bc
∗ + abc
Aplicações de pilhas
55
Entrada
3 5 + 2 ∗ 10 3 − 2/−
5 + 2 ∗ 10 3 − 2/−
+2 ∗ 10 3 − 2/−
2 ∗ 10 3 − 2/−
∗10 3 − 2/−
10 3 − 2/−
3 − 2/−
−2/−
2/−
/−
−
Vazia
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Aplicações de pilhas
56
Exemplo: transformação de notação infixa para pós-fixa
Transformação de notação infixa para pós-fixa (cont.)
a ∗ b + c ∗ d e /f − g ∗ h
Entrada infixa:
Saı́da pós-fixa:
Saı́da
a
a
ab
ab∗
ab∗
ab ∗ c
ab ∗ c
ab ∗ cd
ab ∗ cd
ab ∗ cde
ab ∗ cde∧
a ∗ b + c ∗ d ∧ e / f −g ∗ h
a b ∗ c d e ∧ ∗ f /+g h ∗−
I
As varáveis são copiadas diretamente para a saı́da.
I
Os operadores precisam ser lembrados numa pilha.
I
Um operador é copiado da pilha para a saı́da somente quando aparece
na entrada um operador de prioridade menor ou igual.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Aplicações de pilhas
Pilha
∗
∗
+
+
+∗
+∗
+∗∧
+∗∧
+∗
Entrada
a ∗ b + c ∗ d ∧ e/f − g ∗ h
∗ b + c ∗ d ∧ e/f − g ∗ h
b + c ∗ d ∧ e/f − g ∗ h
+ c ∗ d ∧ e/f − g ∗ h
+ c ∗ d ∧ e/f − g ∗ h
c ∗ d ∧ e/f − g ∗ h
∗d ∧ e/f − g ∗ h
d ∧ e/f − g ∗ h
∧ e/f − g ∗ h
e/f − g ∗ h
/f − g ∗ h
/f − g ∗ h
(continua)
57
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Aplicações de pilhas
58
Transformação de notação infixa para pós-fixa (cont.)
Saı́da
ab ∗ cde ∧ ∗
ab ∗ cde ∧ ∗
ab ∗ cde ∧ ∗f
ab ∗ cde ∧ ∗f /
ab ∗ cde ∧ ∗f /+
ab ∗ cde ∧ ∗f /+
ab ∗ cde ∧ ∗f / + g
ab ∗ cde ∧ ∗f / + g
ab ∗ cde ∧ ∗f / + gh
ab ∗ cde ∧ ∗f / + gh∗
ab ∗ cde ∧ ∗f / + gh ∗ −
Pilha
+
+/
+/
+
−
−
−∗
−∗
−
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Entrada
/f − g ∗ h
f −g∗h
−g∗h
−g∗h
−g∗h
g∗h
∗h
h
Aplicações de pilhas
Exemplos de recursão
59
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de recursão
60
Exemplo 1: função fatorial
Exemplo 2: números de Fibonacci
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...
int f a t o r i a l ( int n) {
i f ( n==0)
return 1;
else
r e t u r n n∗ f a t o r i a l ( n −1);
}
int fibo ( int n) {
i f ( n<=1)
return n ;
else
r e t u r n f i b o ( n−1)+ f i b o ( n −2);
}
int f a t o r i a l ( int n) {
i n t i , f =1;
f o r ( i =1; i <=n ; i ++)
f = f∗i ;
return f ;
}
int fibo ( int n) {
i n t f 1 =0, f 2 =1 , f 3 , i ;
f o r ( i =1; i <=n ; i ++) {
f 3 = f 1+f 2 ;
f1 = f2 ;
f2 = f3 ;
}
return f1 ;
}
Eficiência: ambos O(n) (n multiplicações).
Eficiência:
n = 100:
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de recursão
61
Exemplo 3: Torres de Hanoi
.
..
..
.
O(1.6n )
O(n)
≈ 1020 somas
100 somas
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de recursão
62
Torres de Hanoi: transferência recursiva de N-1 discos
.
..
N
A
B
C
(origem)
(destino)
(auxiliar)
..
.
X
N
Y
Z
Hanoi(X,Z,Y,N-1)
Objetivo: transferir os N discos da torre A para a torre B, usando a torre C
como auxiliar.
Regras:
.
..
I
um disco de cada vez
I
disco de diâmetro maior não pode ficar em cima de um disco de
diâmetro menor
X
Y
..
.
N-1
Z
Solução recursiva: função Hanoi(org,dest,aux,n).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de recursão
63
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de recursão
64
Torres de Hanoi: movimento do maior disco
.
..
X
Y
..
.
Torres de Hanoi: transferência recursiva final de N-1 discos
.
..
N-1
Z
X
Y
Move X para Y
Y
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
..
.
.
..
N-1
Z
Exemplos de recursão
X
65
Torres de Hanoi: função Hanoi
Z
..
.
N
Y
Z
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de recursão
66
Torres de Hanoi: exemplos de saı́da
v o i d Hanoi ( c h a r org , c h a r d e s t , c h a r aux , i n t n ) {
i f ( n>0) {
Hanoi ( org , aux , d e s t , n −1);
p r i n t f ( ”Mova de %c p a r a %c \n” , org , d e s t ) ;
Hanoi ( aux , d e s t , org , n −1);
}
}
I
Chamada inicial: Hanoi(’A’,’B’,’C’,64).
I
Número de movimentos: 2N − 1 (prova por indução).
I
Este é o número mı́nimo.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
N-1
Hanoi(Z,Y,X,N-1)
.
..
X
..
.
Exemplos de recursão
N=1:
N=3:
Mova de A p a r a B
Mova
Mova
Mova
Mova
Mova
Mova
Mova
N=2:
Mova de A p a r a C
Mova de A p a r a B
Mova de C p a r a B
67
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
de
de
de
de
de
de
de
A
A
B
A
C
C
A
para
para
para
para
para
para
para
Exemplos de recursão
B
C
C
B
A
B
B
68
Torres de Hanoi: exemplos de saı́da (cont.)
Exemplo 4: geração de permutações
Problema: Gerar todas as permutações dos m elementos de um vetor.
N=4
Mova
Mova
Mova
Mova
Mova
Mova
Mova
Mova
...
de
de
de
de
de
de
de
de
A
A
C
A
B
B
A
A
para
para
para
para
para
para
para
para
C
B
B
C
A
C
C
B
Mova
Mova
Mova
Mova
Mova
Mova
Mova
de
de
de
de
de
de
de
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
C
C
B
C
A
A
C
para
para
para
para
para
para
para
B
A
A
B
C
B
B
Exemplos de recursão
...
0
69
k-1
Suponha uma função Permuta(k,m) que gera (imprime) todas as
permutações dos elementos de 0 a k-1, seguidas dos elementos de k a
m-1.
I
A chamada inicial Permuta(m,m) resolveria o problema.
I
A solução consistirá em trocar o elemento de ı́ndice k-1
consecutivamente com todos os elementos que o precedem e aplicar a
função recursivamente.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Geração das permutações (cont.)
Passo recursivo: i=k-1, ..., 0
Função Permuta:
...
i
...
k-1
v o i d Permuta ( i n t k , i n t m) {
i f ( k==0)
I m p r i m e (m) ;
else {
int i ;
f o r ( i=k −1; i >=0; i −−) {
Troca ( i , k −1);
Permuta ( k −1,m) ;
Troca ( i , k −1);
}
}
}
m-1
k
Troca(i,k-1)
...
...
i
...
k-1
m-1
k
Permuta(k-1,m)
...
0
...
i
...
k-1
...
...
i
...
k-1
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
k
70
...
0
k-1
k
m-1
m-1
k
Troca(i,k-1)
0
Exemplos de recursão
...
...
0
m-1
I
Geração das permutações (cont.)
0
k
I
A função Imprime imprime os m elementos do vetor.
I
Chamada inicial: Permuta(m,m).
m-1
Exemplos de recursão
71
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de recursão
72
Geração das permutações (cont.)
Saı́da de Permuta(2,3)
1
2
1
3
3
2
2
1
3
1
2
3
3
3
2
2
1
1
Exemplos de retrocesso
Desafio: imprimir em ordem lexicográfica:
1
1
2
2
3
3
2
3
1
3
1
2
3
2
3
1
2
1
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de recursão
73
Exemplo 1: movimentos do cavalo
-1
2
-2
-1
0
2
1
2
1
3
0
4
7
5
74
Um percurso da posição (0,0) até (4,4) (existem 27.419 soluções).
0
1
2
3
0
1
4
9
12
1
10
13
6
3
2
5
2
11
8
7
14
0
1
Exemplos de retrocesso
Movimentos do cavalo (cont.)
Movimentos possı́veis do cavalo no jogo de xadrez:
-2
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
3
6
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
4
Exemplos de retrocesso
75
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
4
15
Exemplos de retrocesso
76
Movimentos do cavalo (cont.)
Movimentos do cavalo (cont.)
Um percurso da posição (0,0) até (4,4) cobrindo todas as posições:
0
1
2
3
4
0
1
12
17
6
23
1
18
7
22
11
16
2
13
2
19
24
5
3
8
21
4
15
10
4
3
14
9
20
25
Tipos de solução:
1. Achar uma solução
2. Achar uma solução que cobre todas as posições livres
3. Enumerar todas as soluções
Observação: Esta não é a melhor maneira de resolver este problema mas
ilustra bem o mecanismo geral de retrocesso.
Obs.: Não existe solução para o tabuleiro da transparência anterior
(provar!).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de retrocesso
77
Movimentos do cavalo (cont.)
Exemplos de retrocesso
78
Movimentos do cavalo: achar uma solução
#d e f i n e TAM MAX 20
#d e f i n e NUM MOV 8
t y p e d e f enum { f a l s e , t r u e } B o o l e a n ;
i n t t a b [TAM MAX ] [ TAM MAX ] ;
i n t d l [NUM MOV] = { −1, −2, −2, −1, 1 , 2 ,
i n t dc [NUM MOV] = { 2 , 1 , −1, −2, −2, −1,
v o i d ImprimeTab ( i n t tam ) {
int i , j ;
f o r ( i =0; i <tam ; i ++) {
f o r ( j =0; j <tam ; j ++)
p r i n t f ( ”%5d” , t a b [ i ] [ j ] ) ;
p r i n t f ( ” \n” ) ;
}
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
2,
1,
-2
-1
-1
2
-2
};
};
1
2
0
B o o l e a n TentaMovimento ( i n t tam , i n t num , i n t l i n ,
i n t c o l , i n t l d , i n t cd ) {
int k ,
l p , cp ;
Boolean r e s = f a l s e ;
i f ((0<= l i n ) && ( l i n <tam ) && (0<= c o l ) &&
( c o l <tam ) && ( t a b [ l i n ] [ c o l ]==0)) {
t a b [ l i n ] [ c o l ] = num ;
i f ( ( l i n==l d ) && ( c o l==cd ) ) {
r e s = t r u e ; ImprimeTab ( tam ) ;
} else { k = 0;
do { l p = l i n +d l [ k ] ; cp = c o l+dc [ k ] ;
r e s = TentaMovimento ( tam , num+1 , l p , cp , l d , cd ) ;
k++;
} w h i l e ( ( ! r e s ) && ( k<NUM MOV ) ) ;
}
tab [ l i n ] [ c o l ] = 0;
}
return res ;
}
1
2
1
3
0
4
7
0
1
2
5
6
Chamada inicial: TentaMovimento(tam,1,lo,co,ld,cd)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de retrocesso
79
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de retrocesso
80
Movimentos do cavalo: exemplo de entrada e saı́da
0
0
1
2
3
1
2
3
Movimentos do cavalo: achar uma solução completa
B o o l e a n TentaMovimento ( i n t tam , i n t num , i n t l i n ,
i n t c o l , i n t l d , i n t cd , i n t noc ) {
int k ,
l p , cp ;
Boolean r e s = f a l s e ;
i f ((0<= l i n ) && ( l i n <tam ) && (0<= c o l ) &&
( c o l <tam ) && ( t a b [ l i n ] [ c o l ]==0)) {
t a b [ l i n ] [ c o l ] = num ;
i f ( ( l i n==l d ) && ( c o l==cd ) && ( ( noc+num)==tam∗tam ) ) {
r e s = t r u e ; ImprimeTab ( tam ) ;
} else { k = 0;
do { l p = l i n +d l [ k ] ;
cp = c o l+dc [ k ] ;
res =
TentaMovimento ( tam , num+1, l p , cp , l d , cd , noc ) ;
k++;
} w h i l e ( ( ! r e s ) && ( k<NUM MOV ) ) ;
}
tab [ l i n ] [ c o l ] = 0;
}
return res ;
}
4
1 4 9 12
10 13 6 3
5 2 11 8
7 14
15
4
Entrada
S aı́ d a
−−−−−−−−−− −−−−−−−−−−−−−−−−−−−−−−−
5
0
4
0
3
4
−1
0
4
4
4
0
−1
1
10
5
0
−1
4
13
2
7
0
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
9
6
11
14
0
12
3
8
0
0
−1
0
0
−1
15
Chamada inicial: TentaMovimento(tam,1,lo,co,ld,cd,ocupadas)
Exemplos de retrocesso
81
Movimentos do cavalo: achar todas as soluções
82
RECURSÃO E RETROCESSO
RCURÇÃO ER RTROCESOS
ˆ ˆ
ˆ ˆ
ˆ ˆ
|
|
|
|
| |
I S
R I
I R
I
Operações elementares:
I
I
I
I
Chamada inicial: TentaMovimento(tam,1,lo,co,ld,cd)
Exemplos de retrocesso
Exemplos de retrocesso
Exemplo 2: distância de edição
v o i d TentaMovimento ( i n t tam , i n t num , i n t l i n ,
i n t c o l , i n t l d , i n t cd ) {
int k ,
l p , cp ;
i f ((0<= l i n ) && ( l i n <tam ) && (0<= c o l ) &&
( c o l <tam ) && ( t a b [ l i n ] [ c o l ]==0)) {
t a b [ l i n ] [ c o l ] = num ;
i f ( ( l i n==l d ) && ( c o l==cd ) ) {
ImprimeTab ( tam ) ;
} else { k = 0;
do { l p = l i n +d l [ k ] ;
cp = c o l+dc [ k ] ;
TentaMovimento ( tam , num+1, l p , cp , l d , cd ) ;
k++;
} w h i l e ( k<NUM MOV) ;
}
tab [ l i n ] [ c o l ] = 0;
}
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
83
A: avanço (subentendido)
I: inserção
S: substituição
R: remoção
I
Cada operação recebe um custo (avanço, em geral, zero)
I
Problema: achar uma sequência de operações que torna as cadeias
iguais ao custo total mı́nimo.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de retrocesso
84
Distância de edição: função Distancia
Distância de edição: desafios
i n t D i s t a n c i a ( char ∗ t e s t e , char ∗ c o r r e t a ) {
i n t d I n s , dRem , dSub ;
i f ( ( ( ∗ t e s t e )==NUL CHAR) && ( ( ∗ c o r r e t a )==NUL CHAR ) )
return 0;
d I n s = dRem = dSub = INT MAX ;
i f ( ( ( ∗ t e s t e )!=NUL CHAR) && ( ( ∗ c o r r e t a )!=NUL CHAR) &&
( ( ∗ t e s t e )==(∗ c o r r e t a ) ) )
r e t u r n D i s t a n c i a ( t e s t e +1 , c o r r e t a +1);
i f ( ( ( ∗ t e s t e )!=NUL CHAR) && ( ( ∗ c o r r e t a )!=NUL CHAR ) )
dSub = c u s t o S u b+D i s t a n c i a ( t e s t e +1 , c o r r e t a +1);
i f ( ( ∗ t e s t e )!=NUL CHAR)
dRem = custoRem+D i s t a n c i a ( t e s t e +1 , c o r r e t a ) ;
i f ( ( ∗ c o r r e t a )!=NUL CHAR)
d I n s = c u s t o I n s+D i s t a n c i a ( t e s t e , c o r r e t a +1);
r e t u r n min ( d I n s , min ( dRem , dSub ) ) ;
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de retrocesso
85
I
Melhorar o desempenho do algoritmo: o algoritmo é exponencial não
sendo viável, sob esta forma, em aplicações práticas
I
Imprimir o número de operações de cada tipo (avanço, inserção,
remoção e substituição) para obter a solução
I
Imprimir a sequência de operações para obter a solução
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de retrocesso
86
Esquema de função recursiva
v o i d Exemplo ( T1 x1 , T2 x2 , . . . ) {
S1 y1 ; S2 y2 ; . . . ;
C i ; /∗ Comandos i n i c i a i s ∗/
i f (E ( . . . ) ) {
C0 ;
/∗ Caso b a s e ∗/
} e l s e { /∗ Chamadas r e c u r s i v a s ∗/
C1 ; Exemplo ( e11 , e12 , . . . ) ;
C2 ; Exemplo ( e21 , e22 , . . . ) ;
C3 ; Exemplo ( e31 , e32 , . . . ) ;
...;
Cm; Exemplo ( em1 , em2 , . . . ) ;
Cf ;
}
}
Eliminação da recursão
Os sı́mbolos Ci, C0, C1, . . ., Cm e Cf representam sequências,
possivelmente vazias, de comandos.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Eliminação da recursão
87
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Eliminação da recursão
88
Esquema de eliminação da recursão
Esquema de eliminação da recursão (cont.)
t y p e d e f enum { chamada1 , chamada2 , chamada3 , . . . } Chamadas ;
t y p e d e f enum { e n t r a d a , s a i d a , r e t o r n o } Acoes ;
v o i d Exemplo ( T1 x1 , T2 x2 , . . . ) {
S1 y1 ; S2 y2 ; . . . ;
/∗ v a r i á v e i s l o c a i s o r i g i n a i s ∗/
T1 t1 , T2 t2 , . . . ;
/∗ v a r i á v e i s t e m p o r á r i a s ∗/
P i l h a f ; Chamadas ch ; Acoes a c a o ;
I n i c i a l i z a P i l h a (& f ) ; a c a o = e n t r a d a ;
do {
switch ( acao ) {
v o i d Exemplo ( T1 x1 , T2 x2 , . . . )
c a s e ( e n t r a d a ) : . . . break ;
S1 y1 ; S2 y2 ; . . . ;
C i ; /∗ Comandos i n i c i a i s ∗/
c a s e ( r e t o r n o ) : . . . break ;
i f (E ( . . . ) ) {
C0 ;
/∗ Caso b a s e ∗/
case ( s a i d a ) :
break ;
} else {
}
/∗ Chamadas r e c u r s i v a s ∗/
C1 ;
Exemplo ( e11 , e12 , . . . ) ;
} w h i l e ( a c a o != s a i d a ) ;
C2 ;
Exemplo ( e21 , e22 , . . . ) ;
}
C3 ;
Exemplo ( e31 , e32 , . . . ) ;
{
case ( e n t r a d a ) :
Ci ;
/∗ Comandos i n i c i a i s ∗/
i f (E ( . . . ) ) {
C0 ;
a c a o = r e t o r n o ; /∗ Caso b a s e ∗/
} else {
/∗ P r i m e i r a chamada r e c u r s i v a ∗/
C1 ; E m p i l h a ( f , x1 , x2 , . . . , y1 , y2 , . . . , chamada1 ) ;
t 1 = e11 ; t 2 = e12 ; . . . ;
x1 = t 1 ; x2 = t 2 ;
...;
/∗ R e c a l c u l a a r g u m e n t o s ∗/
}
break ;
v o i d Exemplo ( T1 x1 , T2 x2 , . . . ) {
S1 y1 ; S2 y2 ; . . . ;
C i ; /∗ Comandos i n i c i a i s ∗/
i f (E ( . . . ) ) {
C0 ;
/∗ Caso b a s e ∗/
} else {
/∗ Chamadas r e c u r s i v a s ∗/
C1 ;
Exemplo ( e11 , e12 , . . . ) ;
C2 ;
Exemplo ( e21 , e22 , . . . ) ;
C3 ;
Exemplo ( e31 , e32 , . . . ) ;
...;
Cm;
Exemplo ( em1 , em2 , . . . ) ;
Cf ;
}
}
...;
Cm;
Exemplo ( em1 , em2 , . . . ) ;
Cf ;
}
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Eliminação da recursão
89
Esquema de eliminação da recursão (cont.)
case ( r e t o r n o ) :
i f ( P i l h a V a z i a ( f ) ) acao = s a i d a ;
else {
D e s e m p i l h a ( f ,& x1 ,& x2 , . . . , & y1 ,& y2 , . . . , & ch ) ;
s w i t c h ( ch ) {
c a s e ( chamada1 ) :
C2 ; E m p i l h a ( f , x1 , x2 , . . . , y1 , y2 , . . . , chamada2 ) ;
t 1 = e21 ; t 2 = e22 ; . . . ;
x1 = t 1 ; x2 = t 2 ; . . . ;
a c a o = e n t r a d a ; break ;
c a s e ( chamada2 ) :
C3 ; E m p i l h a ( f , x1 , x2 , . . . , y1 , y2 , . . . , chamada3 ) ;
v o i d Exemplo ( T1 x1 , T2 x2 , . . . )
t 1 = e31 ; t 2 = e32 ; . . . ;
S1 y1 ; S2 y2 ; . . . ;
x1 = t 1 ; x2 = t 2 ; . . . ;
C i ; /∗ Comandos i n i c i a i s ∗/
i f (E ( . . . ) ) {
a c a o = e n t r a d a ; break ;
C0 ;
/∗ Caso b a s e ∗/
...;
} else {
/∗ Chamadas r e c u r s i v a s ∗/
c a s e ( chamadam ) :
C1 ;
Exemplo ( e11 , e12 , . . . ) ;
C2 ;
Exemplo ( e21 , e22 , . . . ) ;
Cf ; break ;
C3 ;
Exemplo ( e31 , e32 , . . . ) ;
} /∗ s w i t c h ( ch ) ∗/
...;
Cm;
Exemplo ( em1 , em2 , . . . ) ;
}
Cf ;
break ;
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Eliminação da recursão
90
Eliminação da recursão
92
Exemplo 1: função fatorial
{
int f a t o r i a l ( int n) {
i f ( n==0)
return 1;
else
r e t u r n n∗ f a t o r i a l ( n −1);
}
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Eliminação da recursão
91
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Função fatorial (cont.)
Função fatorial (cont.)
t y p e d e f enum { chamada1 } Chamadas ;
t y p e d e f enum { e n t r a d a , s a i d a , r e t o r n o } Acoes ;
int f a t o r i a l ( int n) {
i n t res , t1 ;
P i l h a f ; Chamadas ch ; Acoes a c a o ;
I n i c i a l i z a P i l h a (& f ) ; a c a o = e n t r a d a ;
do {
switch ( acao ) {
c a s e ( e n t r a d a ) : . . . break ;
c a s e ( r e t o r n o ) : . . . break ;
case ( s a i d a ) :
break ;
}
} w h i l e ( a c a o != s a i d a ) ;
return res ;
} /∗ f a t o r i a l ∗/
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
case ( e n t r a d a ) :
i f ( n==0) {
r e s = 1 ; acao = r e t o r n o ;
} else {
E m p i l h a ( f , n , chamada1 ) ;
t 1 = n ; n = t1 −1;
}
break ;
int f a t o r i a l ( int n) {
i f ( n==0)
return 1;
else
r e t u r n n∗ f a t o r i a l ( n −1);
}
Eliminação da recursão
93
Função fatorial (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Eliminação da recursão
94
Exemplo 2: função Hanoi
case ( r e t o r n o ) :
i f ( P i l h a V a z i a ( f ) ) acao = s a i d a ;
else {
D e s e m p i l h a ( f ,&n ,& ch ) ;
int f a t o r i a l ( int n) {
s w i t c h ( ch ) {
i f ( n==0)
return 1;
c a s e ( chamada1 ) :
else
r e s = n∗ r e s ;
r e t u r n n∗ f a t o r i a l ( n −1);
}
break ;
}
break ;
v o i d Hanoi ( c h a r org , c h a r d e s t , c h a r aux , i n t n ) {
i f ( ! ( n >0))
;
else {
Hanoi ( org , aux , d e s t , n −1);
p r i n t f ( ”Mova de %c p a r a %c \n” , org , d e s t ) ;
Hanoi ( aux , d e s t , org , n −1);
}
}
Obs.: Note como neste caso a variável res é usada para guardar o
resultado da função.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
int f a t o r i a l ( int n) {
i f ( n==0)
return 1;
else
r e t u r n n∗ f a t o r i a l ( n −1);
}
Eliminação da recursão
95
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Eliminação da recursão
96
Função Hanoi (cont.)
Função Hanoi (cont.)
t y p e d e f enum { chamada1 , chamada2 } ;
t y p e d e f enum { e n t r a d a , s a i d a , r e t o r n o } Acoes ;
v o i d Hanoi ( c h a r org , c h a r d e s t , c h a r aux , i n t n ) {
char t1 ; char t2 ; char t3 ; i n t t4 ;
P i l h a f ; Chamadas ch ; Acoes a c a o ;
I n i c i a l i z a P i l h a (& f ) ; a c a o = e n t r a d a ;
do {
switch ( acao ) {
c a s e ( e n t r a d a ) : . . . ; break ;
c a s e ( r e t o r n o ) : . . . ; break ;
c a s e ( s a i d a ) : break ;
v o i d Hanoi ( c h a r org , c h a r d e s t , c h a r
}
i f ( ! ( n >0))
;
} w h i l e ( a c a o != s a i d a ) ;
else {
}
Hanoi ( org , aux , d e s t , n −1);
case ( e n t r a d a ) :
i f ( ! ( n >0)) {
acao = r e t o r n o ;
} else {
E m p i l h a ( f , org , d e s t , aux , n , chamada1 ) ;
t 1 = o r g ; t 2 = aux ; t 3 = d e s t ; t 4 = n −1;
o r g = t 1 ; d e s t = t 2 ; aux = t 3 ; n = t 4 ;
}
break ;
aux , i n t n ) {
p r i n t f ( ”Mova de %c p a r a %c\n” , org , d e s t ) ;
Hanoi ( aux , d e s t , org , n −1);
}
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Eliminação da recursão
97
Função Hanoi (cont.)
v o i d Hanoi ( c h a r org , c h a r d e s t , c h a r aux , i n t n ) {
i f ( ! ( n >0))
;
else {
Hanoi ( org , aux , d e s t , n −1);
p r i n t f ( ”Mova de %c p a r a %c\n” , org , d e s t ) ;
Hanoi ( aux , d e s t , org , n −1);
}
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Eliminação da recursão
98
Exemplo de eliminação da recursão caudal
case ( r e t o r n o ) :
i f ( PilhaVazia ( f ))
acao = s a i d a ;
else {
D e s e m p i l h a ( f ,& org ,& d e s t ,& aux ,&n ,& ch ) ;
s w i t c h ( ch ) {
c a s e ( chamada1 ) :
p r i n t f ( ”Mova de %c p a r a %c \n” , org , d e s t ) ;
E m p i l h a ( f , org , d e s t , aux , n , chamada2 ) ;
t 1 = aux ; t 2 = d e s t ; t 3 = o r g ; t 4 = n −1;
o r g = t 1 ; d e s t = t 2 ; aux = t 3 ; n = t 4 ;
acao = e n t r a d a ;
break ;
c a s e ( chamada2 ) : v o i d Hanoi ( c h a r org , c h a r d e s t , c h a r aux , i n t n ) {
i f ( ! ( n >0))
break ;
;
}
else {
Hanoi ( org , aux , d e s t , n −1);
break ;
p r i n t f ( ”Mova de %c p a r a %c\n” , org , d e s t ) ;
Hanoi ( aux , d e s t , org , n −1);
}
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Eliminação da recursão
99
Aplicável quando a última ação dentro do corpo da função é uma
chamada recursiva: reaproveita o mesmo registro de ativação da função,
mudando os valores dos argumentos.
v o i d Hanoi ( c h a r org , c h a r d e s t , c h a r aux , i n t n ) {
i f ( n>0) {
Hanoi ( org , aux , d e s t , n −1);
p r i n t f ( ”Mova de %c p a r a %c \n” , org , d e s t ) ;
Hanoi ( aux , d e s t , org , n −1);
}
}
v o i d Hanoi ( c h a r org , c h a r d e s t , c h a r aux , i n t n ) {
char t ;
w h i l e ( n>0) {
Hanoi ( org , aux , d e s t , n −1);
p r i n t f ( ”Mova de %c p a r a %c \n” , org , d e s t ) ;
t = org ;
o r g = aux ; aux = t ;
}
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Eliminação da recursão
100
Exemplo simples de recursão mútua
int g( int n );
Recursão mútua: Análise sintática
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Recursão mútua: Análise sintática
101
Análise de expressões
int g( int n) {
i f ( n==0)
return 1;
else
r e t u r n f ( n −1);
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Recursão mútua: Análise sintática
102
Programa de tradução de infixa para pós-fixa:
Expressões com operadores binários ‘+’, ‘−’, ‘∗’, ‘/’ e parênteses ‘(’ e ‘)’:
e = t1 ⊕ t2 ⊕ · · · ⊕ tn ,
n≥1
t = f1 ⊗ f2 ⊗ · · · ⊗ fn ,
n≥1
f =x
int f ( int n) {
i f ( n==0)
return 0;
else
r e t u r n g ( n −1);
}
ou
void Expressao ( ) ;
v o i d Termo ( ) ;
void Fator ( ) ;
void InPos () {
pe = &e n t r a d a [ 0 ] ;
Expressao ( ) ;
i f ( ( ∗ pe )!= ’ \0 ’ )
Erro ( ) ;
}
f = (e)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Recursão mútua: Análise sintática
c h a r e n t r a d a [TAM MAX ] ;
c h a r ∗ pe ;
103
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Recursão mútua: Análise sintática
104
Fator
f =x
Termo
ou
f = (e)
t = f1 ⊗ f2 ⊗ · · · ⊗ fn ,
void Fator () {
c h a r c o r r e n t e = ∗ pe ;
switch ( c o r r e n t e ) {
case ’ a ’ :
case ’ b ’ : . . . :
case ’ z ’ :
S a i ( c o r r e n t e ) ; pe++; break ;
case ’ ( ’ :
pe++;
Expressao ( ) ;
i f ( ( ∗ pe)== ’ ) ’ )
pe++;
else
Erro ( ) ;
break ;
default :
Erro ( ) ;
}
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Recursão mútua: Análise sintática
v o i d Termo ( ) {
c h a r op ;
Fator ( ) ;
do {
op = ∗ pe ;
i f ( ( op==’ ∗ ’ ) | | ( op==’ / ’ ) ) {
pe++;
Fator ( ) ;
S a i ( op ) ;
} else
break ; /∗ do ∗/
} while ( true ) ;
}
105
Expressão
e = t1 ⊕ t2 ⊕ · · · ⊕ tn ,
n≥1
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Recursão mútua: Análise sintática
106
Operador de exponenciação
n≥1
Fator redefinido:
void Expressao () {
c h a r op ;
Termo ( ) ;
do {
op = ∗ pe ;
i f ( ( op==’+ ’ ) | | ( op==’− ’ ) ) {
pe++;
Termo ( ) ;
S a i ( op ) ;
} else
break ; /∗ do ∗/
} while ( true ) ;
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
f = p1 ∧ p2 ∧ · · · ∧ pn ,
n≥1
Primário:
p=x
ou
p = (e)
Prioridade? Solução:
f =p
Recursão mútua: Análise sintática
107
ou
f =p∧f
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Recursão mútua: Análise sintática
108
Fator redefinido
Primário
p=x
f =p
ou
ou
p = (e)
void Primario () {
c o r r e n t e = ∗ pe ;
switch ( c o r r e n t e ) {
case ’ a ’ :
case ’ b ’ : . . . :
case ’ z ’ :
S a i ( c o r r e n t e ) ; pe++; break ;
case ’ ( ’ :
pe++;
Expressao ( ) ;
i f ( ( ∗ pe)== ’ ) ’ )
pe++;
else
Erro ( ) ;
break ;
default :
Erro ( ) ;
}
}
f =p∧f
void Fator () {
Primario ( ) ;
i f ( ( ∗ pe)== ’ ˆ ’ ) {
pe++;
Fator ( ) ;
Sai ( ’ˆ ’ ) ;
}
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Recursão mútua: Análise sintática
109
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Recursão mútua: Análise sintática
110
Analogia para expressões e termos
e=t
ou
e=e⊕t
t=f
ou
t=t⊗f
Problemas:
I
como distinguir as alternativas
I
repetição infinita no segundo caso (recursão esquerda)
Árvores binárias
void Expressao () {
...;
i f (???)
Termo ( ) ;
else
Expressao ( ) ;
...
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Recursão mútua: Análise sintática
111
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
112
Exemplo de árvore binária 1: pedigree
R. J. B.
Sean
Lakeview
Lois
R. J. B.
Sean
Carina de
Wood Ladge
Ator dos
Seis Irmãos
Exemplo de árvore binária 2: árvore de decisão
Arisca dos
Seis Irmãos
Johnson
Fancy Boots
Lady
Weberly
x1 ≤ x2
V
R. J. B. Hill
R. J. B. Helvetia
Scotland dos Seis Irmãos
Matarazzo’s Beauty
x2 ≤ x3
x2 ≤ x3
V
Carina de Wood Ladge
Jesse James
F
x1 , x2 , x3
V
x1 ≤ x3
V
Sugarted’s Bonnie
I
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
113
Exemplo de árvore geral 1: descendentes
Grego
Clássico
Germânico
Germânico
Setentrional
IndoEuropeu
IndoIraniano
Itálico
Hindustano
I
Persa
Latim
Português
Castelhano
Francês
Italiano
Catalão
Eslavo
Polonês
Russo
Checo
Báltico
Lituano
Letão
x2 , x1 , x3
x2 , x3 , x1
A árvore representa as decisões tomadas por um algoritmo de
ordenação usando operações de comparação; V: verdadeiro, F: falso.
I
Devido à natureza das comparações, a árvore é binária.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
114
Árvores binárias
Hominidae
Subfamı́lia
Hominini
Gênero
115
Gorillini
Homo
Espécie
Homo
sapiens
Subespécie
Homo sapiens
sapiens
I
Ponginae
Homininae
Tribo
A árvore é incompleta e não necessariamente exata.
Cada elemento pode ter um número variável de sucessores: árvore
geral.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
x3 , x1 , x2
F
I
I
I
V
Famı́lia
Inglês
Alemão
Holandês
Dinamarquês
Norueguês
Sueco
Hindi
Urdu
Persa
Antigo
BaltoEslavo
x3 , x2 , x1
Exemplo de árvore geral 2: descendentes
Grego Moderno
Germânico
Ocidental
F
x1 ≤ x3
F
x1 , x3 , x2
Alguns nomes são repetidos: eles devem ser tratados como instâncias
separadas.
Pela própria natureza da árvore, cada elemento tem dois
predecessores: árvore binária.
F
Homo
habilis
Homo
neanderthalensis
Pan
...
Chimpanzé
Bonobo
Gorilla
Pongo
Gorila
Orangotango
Árvore da famı́lia Hominidae determinada por comparação de DNA de
várias espécies (incompleta).
Cada elemento pode ter um número variável de sucessores: árvore
geral.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
116
Exemplo de árvore geral 3: organograma
Definição de árvore binária
UNICAMP
Uma árvore binária é um conjunto de nós que:
IC
DSC
DSI
IMECC
DTC
DE
DM
...
FEEC
DMA
DCA
DEB
...
DT
FCM
DAP
DAN
...
I
ou é vazio (árvore binária vazia)
I
ou contém um nó especial denominado raiz da árvore e o resto do
conjunto está particionado em duas árvores binárias disjuntas
(possivelmente vazias), denominadas subárvore esquerda e subárvore
direita.
DTO
Obs.: A UNICAMP tem 21 unidades acadêmicas. Algumas unidades têm
mais de 10 departamentos.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
117
Representação gráfica, convenções e conceitos
A
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
C
F
Uma árvore binária com n nós tem:
nı́vel 3
I
H
nı́vel 4
I
I
Raiz da árvore: A
Filho esquerdo de A: B
Pai de F : C
Descendentes de B: B, D, E e G
Folhas: D, G e H
Nı́veis: indicados na figura
Subárvores binárias vazias: 9
120
nı́vel 2
I
G
Árvores binárias
Fatos sobre árvores binárias
I
E
118
nı́vel 1
B
D
Árvores binárias
Filho direito de A: C
Irmão de E: D
Antepassados de H: H, F , C e A
Nós internos: todos exceto as folhas
Altura (profundidade) – nı́vel máximo: 4
Subárvores binárias não vazias: 7
I
altura máxima n
altura mı́nima dlog2 (n + 1)e
subárvores vazias: n + 1
subárvores não vazias: n − 1 (se n > 0)
Uma árvore binária de altura h tem:
I
I
no mı́nimo h nós
no máximo 2h − 1 nós
Obs.: Alguns autores começam a numeração dos nı́veis a partir de zero.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
119
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Representação ligada comum
Representação ligada com três apontadores
p
p
A
A
B
B
C
D
E
C
D
F
G
E
G
H
Árvores binárias
H
O terceiro apontador possibilita descer e subir pela estrutura,
analogamente às listas duplamente ligadas.
O acesso a todos os nós da árvore pode ser realizado através de um
apontador para a raiz.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
F
121
Representação com o campo pai apenas
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
122
Representação seqüencial: árvores binárias completas
A
0
A
B
C
B
I
1
2
C
3
D
E
F
G
J
M
4
5
6
D
E
G
H
K
L
N
O
7
8
9
10
11
12
13
14
H
Problemas:
I
É necessário haver acesso (apontadores) pelo menos a todas as folhas.
I
Não é possı́vel distinguir entre os filhos esquerdos e direitos.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
F
Árvores binárias
123

 filho esquerdo: 2n + 1 (n ≥ 0)
filho direito:
2n + 2 (n ≥ 0)
Nó n:

pai:
b(n − 1)/2c (n > 0)
A
B
I
C
F
J
M
D
E
G
H
K
L
N
O
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
124
Representação seqüencial: árvores binárias quase completas
Percursos em profundidade
I
Pré-ordem:
Visitar a raiz
Percorrer a subárvore esquerda em pré-ordem
Percorrer a subárvore direita em pré-ordem
I
Pós-ordem:
Percorrer a subárvore esquerda em pós-ordem
Percorrer a subárvore direita em pós-ordem
Visitar a raiz
I
Inordem (ou ordem simétrica):
Percorrer a subárvore esquerda em inordem
Visitar a raiz
Percorrer a subárvore direita em inordem
A
0
B
I
1
2
C
F
J
M
3
4
5
6
D
E
G
H
K
7
8
9
10
11
A
B
I
C
F
J
M
D
E
G
H
K
0
1
2
3
4
5
6
7
8
9
10
11
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
125
Exemplos de percurso em profundidade
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
126
Percurso em largura
Percurso por nı́veis, da esquerda para a direita:
A
A
B
nı́vel 1
C
B
D
E
C
F
D
G
nı́vel 2
E
F
nı́vel 3
H
G
H
nı́vel 4
Pré-ordem: A,B,D,E,G,C,F ,H
Pós-ordem: D,G,E,B,H,F ,C,A
Inordem: D,B,G,E,A,F ,H,C
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Percurso: A,B,C,D,E,F ,G,H
Árvores binárias
127
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
128
Implementação recursiva de percursos
t y p e d e f s t r u c t NoArvBin {
T info ;
s t r u c t NoArvBin ∗ esq , ∗ d i r ;
} NoArvBin , ∗ A r v B i n ;
v o i d InOrdem ( A r v B i n p ) {
i f ( p!=NULL) {
InOrdem ( p−>e s q ) ;
Visita (p );
InOrdem ( p−>d i r ) ;
}
} /∗ InOrdem ∗/
Eliminação da recursão caudal
v o i d PreOrdem ( A r v B i n p ) {
i f ( p!=NULL) {
Visita (p );
PreOrdem ( p−>e s q ) ;
PreOrdem ( p−>d i r ) ;
}
} /∗ PreOrdem ∗/
v o i d PosOrdem ( A r v B i n p ) {
i f ( p!=NULL) {
PosOrdem ( p−>e s q ) ;
PosOrdem ( p−>d i r ) ;
Visita (p );
}
} /∗ PosOrdem ∗/
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
129
Percurso em pré-ordem, usando uma pilha explı́cita
v o i d PreOrdem ( A r v B i n p ) {
i f ( p!=NULL) {
Visita (p );
PreOrdem ( p−>e s q ) ;
PreOrdem ( p−>d i r ) ;
}
} /∗ PreOrdem ∗/
v o i d PreOrdem ( A r v B i n p ) {
w h i l e ( p!=NULL) {
Visita (p );
PreOrdem ( p−>e s q ) ;
p = p−>d i r ;
}
} /∗ PreOrdem ∗/
I
Transformação análoga pode ser feita para a inordem.
I
E a pós-ordem?
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
X
E
Visita X
Árvores binárias
130
Percurso em pré-ordem, usando uma pilha explı́cita (cont.)
A figura indica a situação inicial e final do percurso de uma árvore
arbitrária (pode ser vazia). Inicialmente, o apontador para a árvore deve
estar no topo da pilha. Terminado o percurso, a pilha terá um elemento a
menos.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
131
D
Percorre E
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Percorre D
Árvores binárias
132
Percurso em pré-ordem, usando uma pilha (cont.)
Percurso em largura, usando uma fila
Os nós da árvore a serem visitados são guardados numa fila.
v o i d PreOrdem ( A r v B i n p ) {
Pilha pl ;
I n i c i a l i z a P i l h a (& p l ) ;
E m p i l h a (& p l , p ) ;
do {
D e s e m p i l h a (& p l ,&p ) ;
i f ( p!=NULL) {
Visita (p );
E m p i l h a (& p l , p−>d i r ) ;
E m p i l h a (& p l , p−>e s q ) ;
}
} while ( ! PilhaVazia ( pl ) ) ;
} /∗ PreOrdem ∗/
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
X
nı́vel k
nı́vel k+1
E
D
Visita X
Árvores binárias
133
Percurso em largura, usando uma fila (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
134
Comparação dos percursos em pré-ordem e em largura
v o i d PreOrdem ( A r v B i n p ) {
Pilha pl ;
I n i c i a l i z a P i l h a (& p l ) ;
E m p i l h a (& p l , p ) ;
do {
D e s e m p i l h a (& p l ,&p ) ;
i f ( p!=NULL) {
Visita (p );
E m p i l h a (& p l , p−>d i r ) ;
E m p i l h a (& p l , p−>e s q ) ;
}
} while ( ! PilhaVazia ( pl ) ) ;
} /∗ PreOrdem ∗/
void Largura ( ArvBin p ) {
Fila fl ;
I n i c i a l i z a F i l a (& f l ) ;
I n s e r e F i l a (& f l , p ) ;
do {
R e m o v e F i l a (& f l ,&p ) ;
i f ( p!=NULL) {
Visita (p );
I n s e r e F i l a (& f l , p−>e s q ) ;
I n s e r e F i l a (& f l , p−>d i r ) ;
}
} while ( ! FilaVazia ( f l ) ) ;
} /∗ L a r g u r a ∗/
void Largura ( ArvBin p ) {
Fila fl ;
I n i c i a l i z a F i l a (& f l ) ;
I n s e r e F i l a (& f l , p ) ;
do {
R e m o v e F i l a (& f l ,&p ) ;
i f ( p!=NULL) {
Visita (p );
I n s e r e F i l a (& f l , p−>e s q ) ;
I n s e r e F i l a (& f l , p−>d i r ) ;
}
} while ( ! FilaVazia ( f l ) ) ;
} /∗ L a r g u r a ∗/
Quase idênticos, exceto a troca de esquerda pela direita!
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
135
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
136
Preordem com pilha otimizada
Pré-ordem com pilha embutida: Deutsch, Schorr e Waite
NULL
v o i d PreOrdem ( A r v B i n p ) {
Pilha pl ;
Boolean fim = f a l s e ;
I n i c i a l i z a P i l h a (& p l ) ;
do {
i f ( p!=NULL) {
Visita (p );
i f ( p−>d i r !=NULL)
E m p i l h a ( p l , p−>d i r ) ;
p = p−>e s q ;
} else i f ( PilhaVazia ( pl ))
fim = true
else
D e s e m p i l h a ( p l ,&p ) ;
} while ( ! fim ) ;
} /∗ PreOrdem ∗/
...
...
...
p
t
...
I
I
I
Árvores binárias
137
Pré-ordem com pilha embutida (cont.)
... ...
...
A variável p aponta para a subárvore a ser percorrida.
A variável t aponta para o topo de uma pilha formada pelos nós que
levam ao nó p (apontadores invertidos).
Cada nó deverá conter uma marca indicando qual dos dois
apontadores está invertido.
A função seguinte implementa os três percursos em profundidade.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
138
Árvores binárias
140
Desafios:
v o i d DSW( A r v B i n p ) {
A r v B i n t = NULL ;
ArvBin q ;
Boolean sobe ;
do {
w h i l e ( p!=NULL) {
/∗ à e s q u e r d a ∗/
P r e V i s i t a ( p ) ; p−>marca = MarcaEsq ; q = p−>e s q ;
p−>e s q = t ; t = p ; p = q ;
}
sobe = t r u e ;
w h i l e ( s o b e && ( t !=NULL ) ) {
s w i t c h ( t−>marca ) {
c a s e MarcaEsq :
/∗ à d i r e i t a ∗/
I n V i s i t a ( t ) ; s o b e = f a l s e ; t−>marca = M arc aD ir ;
q = p ; p = t−>d i r ; t−>d i r = t−>e s q ; t−>e s q = q ;
break ;
c a s e M ar c a D i r :
/∗ s o b e ∗/
P o s V i s i t a ( t ) ; q = t−>d i r ; t−>d i r = p ; p = t ; t = q ;
break ;
}
}
} w h i l e ( t !=NULL ) ;
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
...
...
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
...
Árvores binárias
139
I
melhorar a pré-ordem com pilha otimizada
I
inordem com pilha otimizada
I
pós-ordem com pilha otimizada
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Reconstrução de árvores binárias
Reconstrução de árvores binárias (cont.)
A
Pré-ordem AB:
A
B
B
Inordem AB:
A
A
B
B
Pós-ordem AB:
B
A
I
a partir da pré-ordem, determine a raiz da árvore
I
dada a raiz, ela separa a inordem em inordens das suas subárvores
esquerda e direita
I
a partir da pré-ordem, são determinadas as pré-ordens das subárvores
que têm os mesmos comprimentos das respectivas inordens
I
recursivamente são reconstruı́das as subárvores
A
A
Pré-ordem AB e pós-ordem BA:
Verifica-se facilmente que a pré-ordem (ou a pós-ordem) combinada com a
inordem determinam, de maneira única, a forma da árvore. No caso da
pré-ordem e inordem, pode-se seguir o seguinte algoritmo:
B
B
A
B
Conclusão: uma única ordem e a combinação de pré- e pós-ordens não
determinam a árvore de maneira única.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
O caso da pós-ordem é análogo.
141
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
142
Representações externas de árvores binárias
A
B
I
I
percursos canônicos: inordem e pré (ou pós)
-ordem (já visto):
DBGEAF HC
ABDEGCF H
C
D
E
F
G
H
Árvores binárias de busca
percurso canônico com indicadores de subárvores (pré-ordem):
A11 B11 D00 E10 G00 C10 F01 H00
O ı́ndice 0 indica a ausência e 1 indica a existência de filho esquerdo
ou direito.
I
descrição parentética (inordem):
(((()D())B((()G())E()))A((()F (()H()))C()))
() representa uma árvore vazia; (αXβ) representa uma árvore de raiz
X e subárvores descritas pelas cadeias α e β.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias
143
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
144
Exemplo de árvore de busca: números
Exemplo de árvore de busca: nomes
jul
16
set
fev
8
27
ago
5
15
jan
out
mai
21
abr
10
Para qualquer nó da árvore, os elementos da sua subárvore esquerda
(direita) são menores ou iguais (maiores ou iguais) do que o elemento do
nó.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
145
Inserção em árvore de busca
mar
Para qualquer nó da árvore, os elementos da sua subárvore esquerda
(direita) precedem (seguem) em ordem alfabética o elemento do nó.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
146
Inserção recursiva
Y
Y
X <Y
X >Y
Y
Y
B o o l e a n I n s e r e A r v B u s c a ( A r v B i n ∗p , T x ) {
/∗ V e r s ã o r e c u r s i v a ∗/
i f ( ( ∗ p)==NULL) {
∗p = m a l l o c ( s i z e o f ( NoArvBin ) ) ;
( ∗ p)−>e s q = ( ∗ p)−> d i r = NULL ;
( ∗ p)−> i n f o = x ;
return true ;
} else {
T i n f o = ( ∗ p)−> i n f o ;
i f ( x<i n f o )
r e t u r n I n s e r e A r v B u s c a (&((∗ p)−>e s q ) , x ) ;
e l s e i f ( x>i n f o )
r e t u r n I n s e r e A r v B u s c a (&((∗ p)−> d i r ) , x ) ;
else
return f a l s e ;
}
}
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
jun
nov
A inserção de um valor X cria uma nova folha em lugar de uma subárvore
vazia. O ponto de inserção é determinado pelo percurso da árvore usando
a propriedade de árvores de busca.
X
dez
25
X
Árvores binárias de busca
I
147
Note-se o uso de passagem de parâmetro p por referência.
Esta versão apresenta somente recursão caudal que pode ser
facilmente eliminada.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
148
Inserção iterativa
Remoção em árvore de busca
Caso 1: pelo menos uma das subárvores é vazia:
B o o l e a n I n s e r e A r v B u s c a ( A r v B i n ∗p , T x ) {
/∗ V e r s ã o i t e r a t i v a ∗/
T info ;
w h i l e ( ( ∗ p )!=NULL) {
i n f o = ( ∗ p)−> i n f o ;
i f ( x<i n f o )
p = &((∗ p)−>e s q ) ;
e l s e i f ( x>i n f o )
p = &((∗ p)−> d i r ) ;
else
return f a l s e ;
}
∗p = m a l l o c ( s i z e o f ( NoArvBin ) ) ;
( ∗ p)−>e s q = ( ∗ p)−> d i r = NULL ;
( ∗ p)−> i n f o = x ;
return true ;
}
p
X
I
I
I
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
149
Remoção em árvore de busca (cont.)
p é o endereço do campo ou da variável que contém o apontador para
o nó com a informação X.
O caso de ambas as subárvores vazias também está coberto.
O caso de subárvore esquerda vazia mas direita não vazia é análogo.
O nó com a informação X pode ser liberado.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
150
Inserções e remoções em árvores binárias de busca
Caso 2: as duas subárvores são não vazias
I
p
p
Problema: a altura da árvore pode crescer muito já que numa árvore
com n nós:
I
X
X
Y
I
I
Se n ≈ 1.000:
I
I
Y
I
Y
Substituir a informação X por Y – o valor máximo contido na
subárvore esquerda (ou mı́nimo na subárvore direita).
I
I
I
Remover o nó que originalmente continha Y (sua subárvore direita é
vazia – aplica-se o caso 1).
I
Implementação: exercı́cio.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
151
altura máxima 1.000
altura mı́nima 10
Se n ≈ 1.000.000:
I
I
altura máxima n
altura mı́nima dlog2 (n + 1)e
altura máxima 1.000.000
altura mı́nima 20
O pior caso ocorre, por exemplo, quando a inserção é feita em ordem
(crescente ou descrescente)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
152
Árvores de altura balanceada (AVL)
Balanceamento de árvores
I
I
Algoritmo óbvio não garante balanceamento
Balanceamento perfeito (altura mı́nima):
I
I
I
eficiência de busca: O(log n)
eficiência de inserção: O(n) – inaceitável
I
Autores: G. M. Adel’son-Vel’skiı̆ e E. M. Landis (1962)
I
Uma árvore binária de busca é do tipo AVL se ela é vazia, ou então,
se para todos os seus nós a diferença de alturas entre as subárvores
esquerda e direita é no máximo 1, em valor absoluto.
I
A diferença entre as alturas direita e esquerda é chamada fator de
balanceamento.
Balanceamento aproximado:
I
I
árvores AVL – eficiência de busca, inserção e remoção: O(log n)
árvores rubro-negras – eficiência de busca, inserção e remoção:
O(log n)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
153
Exemplos de árvores AVL
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
F0
−
F1
F2
−
0
+
+
0
F3
F4
−
−
−
0
−
0
0
154
Pior caso de desbalanceamento: árvores de Fibonacci
NULL
0
Árvores binárias de busca
−
0
−
−
0
−
0
0
0
Forma geral – altura h ≥ 2:
Fh
0
−
Note-se que a primeira árvore é de altura mı́nima enquanto que a segunda
não é.
Fh−1
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
155
Fh−2
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
156
Árvores de Fibonacci: propriedades
Inserção em árvores AVL
−
Fh−1
A explicação a seguir supõe que a inserção é realizada por uma função
recursiva cujo cabeçalho é:
Fh−2
I
Para uma dada altura h, a árvore contém o número mı́nimo de nós
possı́vel preservando ainda a propriedade AVL.
I
Qualquer outra árvore AVL com o mesmo número de nós tem altura
menor ou igual – este é o pior caso.
I
Número de nós de Fh : N (h) = N (h − 1) + N (h − 2) + 1,
I
Demonstra-se por indução: N (h) = fh+2 − 1, onde fi é o i-ésimo
número de Fibonacci.
p
p
Usando a aproximação fi ≈ ((1 + (5))/2)i / (5) obtém-se:
h ≈ 1, 44 log2 (n + 2) (no máximo).
I
h≥2
B o o l e a n B u s c a I n s e r e ( ArvAVL ∗p , T x , B o o l e a n ∗ a l t ) ;
onde
I
I
I
I
I
I
Operação de busca usará O(log n) operações.
I
A ser visto: inserção e remoção também usarão O(log n) operações.
p: endereço da variável que contém o apontador para a árvore
x: valor a ser inserido de algum tipo T conveniente
alt: endereço da variável na qual é devolvida a informação que indica
se a árvore aumentou ou não de altura
se não houver aumento de altura numa chamada recursiva, o resto da
árvore não sofre mudança
conforme será visto, o aumento da altura será no máximo de um e
pode acontecer somente numa árvore vazia ou então cuja raiz tem
fator de balanceamento igual a zero; neste caso, o fator resultante
será diferente de zero, exceto quando a árvore era vazia.
O valor devolvido pela função indica se a inserção foi efetivamente
realizada ou se o elemento x já pertencia à arvore.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
157
Inserção em árvores AVL (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Explicação geral: caso de chamada recursiva com aumento de altura
p
x
α
alt: ?
158
Inserção em árvores AVL (cont.)
Explicação geral: caso de chamada recursiva sem aumento de altura
p
Árvores binárias de busca
p
x
?
x
α
alt: ?
p
x
alt: false
h
h
α
Neste caso, haverá modificação no nó corrente com possı́vel propagação
para as chamadas anteriores.
Neste caso, não haverá mais modificações na árvore.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
alt: true
h+1
h
α
?
Árvores binárias de busca
159
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
160
Inserção em árvores AVL (cont.)
Inserção em árvores AVL (cont.)
Caso 2: Inserção do lado mais baixo:
+
Caso 1: Inserção em árvore vazia:
0
h
0
NULL
+
h
h
X
x
h=0
x
h=1
alt: true
Neste caso a altura h aumenta. Este fato será propagado no retorno da
função através de valor verdadeiro da variável alt.
Nos casos seguintes, será suposto sempre que a inserção foi realizada na
subárvore esquerda; o caso da inserção do lado direito é análogo.
alt: false
O conteúdo do retângulo representa o resultado da chamada recursiva. O
fator de balanceamento será modificado somente se a árvore esquerda
aumentou de tamanho.
Neste caso a altura permanece inalterada. Este fato será propagado no
retorno da função através de valor falso da variável alt. Como
consequência, o processo de inserção pára (exceto os retornos).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
161
Inserção em árvores AVL (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
162
Inserção em árvores AVL (cont.)
Caso 4: Inserção do lado mais alto
−
−
Caso 3: Inserção quando as duas alturas são iguais
0
h-1
h
−
0
h+1
h
h+1
x
alt: true
h+1
x
alt: true
x
alt: true
Neste caso, se houve aumento de altura na chamada recursiva, a altura
total também aumentará. Este fato será propagado no retorno da função
através de valor verdadeiro da variável alt.
Neste caso, se houve aumento de altura na chamada recursiva, a árvore
deixará de ser do tipo AVL. Haverá então dois subcasos, dependendo do
lado da subárvore esquerda em que houve inserção. A identificação do
subcaso será feita pelo valor do fator de balanceamento final da subárvore
que aumentou de altura durante a chamada recursiva.
Nos dois casos haverá rearranjos convenientes mas locais da árvore.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
163
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
164
Inserção em árvores AVL (cont.)
Inserção em árvores AVL (cont.)
Caso 4a: inserção do lado esquerdo da subárvore (rotação LL)
Caso 4b: inserção do lado direito da subárvore (rotação LR)
−
−
−
−
A
A
+
−
B
B
h-1
h-1
+0−
h+1
C
h+1
T3
T1 h-1
T2
h-2
h-2 T
1
h-2
x
x
x
T4
h-2
T2 h-2/h-3 T3
x
x
alt: true
alt: true
0
0
C
C
−/0
0
0
B
B
0/+
B
A
h
0
A
h
h-2 T
1
T1 h-1
x
T2
h-2 T
3
h-2
x
h-2/h-3
T2
T3
x
x
T4
h-2
x
alt: false
alt: false
Neste caso é realizada uma transformação denominada rotação simples LL
(esquerda, esquerda). A altura final permanece inalterada e a variável alt
recebe valor falso.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
Neste caso, a inserção pode ter sido realizada na subárvore esquerda ou
direita do lado que cresceu, ou então no próprio nó C quando h = 2. Os
fatores de balanceamento finais dependem disto, mas o da raiz será 0. A
transformação é denominada rotação dupla LR (esquerda, direita). A
altura final permanece inalterada e a variável alt recebe valor falso.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
165
Função de inserção em árvores AVL
Árvores binárias de busca
166
Função de inserção em árvores AVL (cont.)
i f ( ∗ a l t ) { /∗ aumento de a l t u r a ∗/
ArvAVL p1 , p2 ;
s w i t c h ( ( ∗ p)−> b a l ) {
c a s e m a i s : ( ∗ p)−> b a l = z e r o ; ∗ a l t = f a l s e ; break ;
c a s e z e r o : ( ∗ p)−> b a l = menos ; break ;
c a s e menos :
p1 = ( ∗ p)−>e s q ;
i f ( p1−>b a l==menos ) {
/∗ R o t a çã o s i m p l e s LL ∗/
} else {
/∗ R o t a çã o d u p l a LR ∗/
}
p1−>b a l = z e r o ; ∗ a l t = f a l s e ;
break ;
}
}
return true ;
} else {
/∗ d e s c e à d i r e i t a − a n á l o g o ∗/
}
B o o l e a n B u s c a I n s e r e ( ArvAVL ∗p , T x , B o o l e a n ∗ a l t ) {
/∗ D e v o l v e ’ t r u e ’ ou ’ f a l s e ’ c o n f o r m e houve ou não i n s e r ç ã o ;
s e houve i n s e r ç ã o , ’ a l t ’ i n d i c a s e houve aumento da a l t u r a .
∗/
i f ( ∗ p==NULL) {
∗p = m a l l o c ( s i z e o f ( NoArvAVL ) ) ;
( ∗ p)−>e s q = ( ∗ p)−> d i r = NULL ; ( ∗ p)−> i n f o = x ;
( ∗ p)−> b a l = z e r o ; ∗ a l t = t r u e ;
return true ;
} else {
T i n f o = ( ∗ p)−> i n f o ;
i f ( x==i n f o )
return f a l s e ;
e l s e i f ( x<i n f o ) { /∗ d e s c e à e s q u e r d a ∗/
B o o l e a n r e s = B u s c a I n s e r e (&((∗ p)−>e s q ) , x , a l t ) ;
i f (! res )
return f a l s e ;
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
167
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
168
Exemplos de inserção em árvores AVL
Exemplos de inserção em árvores AVL (cont.)
Inserção de 33:
Inserção de 63:
−
50
−
50
−
65
+
25
−
20
0
+
35
−
45
0
10
+
55
30
−
65
+
25
−
20
0
70
0
10
0
40
0
0
60
−
45
30
−
20
0
70
0
0
60
+
35
0
60
− 0
45
55
0
10
0
30
70
0
63
0
40
63
40
Neste caso, a inserção causou uma rotação simples do tipo RR, afetando
os nós marcados.
Árvores binárias de busca
169
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
170
Remoção em árvores AVL
Inserção de 41:
1. Transformação em remoção de uma folha - três casos:
I
−
50
−
50
−
65
+
25
−
20
+
35
+
55
−
45
0
10
+
55
−
65
+
25
0
40
Exemplos de inserção em árvores AVL (cont.)
0
+
35
0
10
Neste caso, houve uma inserção simples e a mudança de fatores de
balanceamento afetou os nós marcados.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
−
65
−
20
0
0
33
−
50
+
25
70
−
45
+
30
0
60
+
55
0
35
0
33
−
50
30
0
60
−
65
+
25
−
20
70
0
I
0
+
35
0
10
0
0
70
0
30
0
41
60
0
40
I
+
55
0
40
2. Remoção propriamente dita.
45
41
Neste caso, a inserção causou uma rotação dupla do tipo LR, afetando os
nós marcados.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
o nó tem grau zero: já é uma folha
o nó tem grau um: pela propriedade AVL, a sua única subárvore é
necessariamente constituı́da por uma folha, cujo valor é copiado para o
nó pai; o nó a ser eliminado é a folha da subárvore
o nó tem grau dois: o seu valor é substitı́do pelo maior valor contido na
sua subárvore esquerda (ou o menor valor contido na sua subárvore
direita); o nó que continha o menor (ou maior) valor copiado tem
necessariamente grau zero ou um, recaindo num dos casos anteriores.
171
3. O algoritmo de remoção será apresentado novamente como uma
função recursiva que indica se houve diminuição da altura da árvore
após a remoção. Serão estudados apenas os casos de remoção do
lado esquerdo; os outros são análogos.
4. A implementação do algoritmo é um exercı́cio.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
172
Remoção em árvores AVL (cont.)
Remoção em árvores AVL (cont.)
Caso 2: Remoção quando as duas alturas são iguais
0
0
+
Caso 1: Remoção de uma folha
h
h
h
NULL
0
X
x
alt: true
h=0
alt: false
h=1
O conteúdo do retângulo representa o resultado da chamada recursiva. O
fator de balanceamento será modificado somente se a árvore esquerda
diminuiu de tamanho.
Neste caso a altura h diminui. Este fato será propagado no retorno da
função através de valor verdadeiro da variável alt.
Neste caso, mesmo que haja diminuição de altura na chamada recursiva, a
altura total permanece a mesma. Este fato será propagado no retorno da
função através de valor falso da variável alt.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
173
Remoção em árvores AVL (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
174
Remoção em árvores AVL (cont.)
Caso 4: Remoção do lado mais baixo
Caso 3: Remoção do lado mais alto
+
−
−
+
0
h
h
h-1
h
x
x
alt: true
alt: true
alt: true
Neste caso, se a chamada recursiva indica diminuição da altura da
subárvore, a altura final da árvore também diminui e o processo continua.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
h-2
h-1
Árvores binárias de busca
175
Caso a subárvore esquerda tenha sua altura diminuı́da, a árvore deixa de
ser do tipo AVL. Há três subcasos, dependendo do fator de balanceamento
do filho direito da raiz.
Note-se que, neste caso, tem-se h ≥ 3.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
176
Remoção em árvores AVL (cont.)
Remoção em árvores AVL (cont.)
Caso 4a: Fator de balanceamento 0 (rotação RR)
Caso 4b: Fator de balanceamento +1 (rotação RR)
+
+
+
A
+
A
0
+
B
h
B
h-2
h
T1 h-3
alt: true
h-2
h-2
T2
h-2
h-3
T3
h-3
T2
h-2
T3
−
−
B
B
0
0
B
B
+
0
A
A
h
h-2
h-3
T2
T3
h-3
T1
h-1
h-1
h-2
T3
h-3
T1
T1
alt: true
T2
h-2
alt: true
alt: false
Neste caso é realizada uma transformação denominada rotação simples RR
(direita, direita). A altura final permanece inalterada e a variável alt
recebe valor falso. O processo de ajuste da árvore pára.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
177
Remoção em árvores AVL (cont.)
Neste caso também é realizada a transformação denominada
rotação simples RR (direita, direita). A altura final diminui e a variável alt
recebe o valor verdadeiro. O processo de ajuste da árvore continua.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
178
Exemplos de remoção em árvores AVL
Caso 4c: Fator de balanceamento -1 (rotação RL)
+
Remoção de 40:
+
A
−
B
h
h-2
h-3
T1
−
50
+0−
C
alt: true
T2 h-3/h-4 T3
T4
h-3
0
0
−/0
−
45
30
25
0
−
20
70
0
60
0
+
55
0
35
0
10
0
70
0
30
45
0
60
0
B
40
h-1
h-3/h-4
T2
T3
T1
+
55
−
65
0
0/+
A
h-3
+
35
0
10
C
C
50
−
65
+
25
−
20
0
0
T4
h-3
alt: true
Neste caso também é realizada uma transformação denominada
rotação dupla RL (direita, esquerda). A altura final diminui e a variável
alt recebe o valor verdadeiro. O processo de ajuste da árvore continua.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
179
Neste caso, houve uma remoção simples e a mudança de fatores de
balanceamento afetou os nós marcados.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
180
Exemplos de remoção em árvores AVL (cont.)
Remoção de 60:
−
50
0
35
−
65
+
25
−
20
0
+
35
−
45
0
10
+
55
30
−
25
0
−
20
70
0
60
−
45
0
30
0
0
10
Árvores do tipo B
+
50
0
65
0
40
0
55
70
(B trees)
0
40
Neste caso, a remoção causou, após a volta da chamada com a raiz
original, uma rotação dupla do tipo LR, afetando os nós marcados.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores binárias de busca
181
Discos magnéticos
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
182
Discos magnéticos (cont.)
Esboço esquemático do corte vertical de uma unidade com quatro discos
(oito superfı́cies):
Esboço esquemático de uma superfı́cie de um disco:
0
..
.
1
2
uma trilha
3
um cilindro
(trilhas iguais)
4
5
6
7
cabeças leitoras/gravadoras
setores
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
183
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
184
Árvores B
Discos magnéticos (cont.)
Dados para um disco fictı́cio de 40 gigabytes:
I
I
I
10 cabeças leitoras/gravadoras
I
20.000 trilhas (2.000 por superfı́cie)
I
400 setores por trilha
I
512 bytes por setor (unidade mı́nima de endereçamento)
I
tempo médio de busca da trilha endereçada (seek): ∆S
(10 milissegundos)
1. todas as folhas de T têm o mesmo nı́vel;
2. cada nó interno tem um número variável r de registros de informação e
r+1 de filhos, onde

 bb/2c ≤ r ≤ b se nó 6= raiz

tempo médio de latência – espera pelo setor endereçado: ∆L
(10 milissegundos)
I
tempo de transferência de dados: ∆T (60 megabytes/segundo)
I
Estes tempos são várias ordens de grandeza maiores do que tempo de
acesso à memória RAM (tipicamente 100.000 vezes).
I
Número de acessos: altura da árvore – log2 n não é mais aceitável
I
Solução: logk n, com k >> 2
Árvores do tipo B
1≤r≤b
se nó = raiz
3. cada folha tem um número variável r de registros obedecendo à mesma
restrição do item anterior;
4. os campos de informação contidos nos registros obedecem à
propriedade de árvores de busca.
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Autores: Rudolf Bayer e Ed McCreight (1971)
T é uma árvore B de ordem b ≥ 2 se:
I
I
Alguns autores definem de maneira diferente o conceito de ordem.
Pode-se provar que a altura máxima h de uma árvore B de ordem b
que contém n registros é dada por:
logbb/2c (n + 1)/2.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
185
Árvores do tipo B
186
Exemplo de árvore B de ordem 3
Exemplo de árvore B de ordem 5
Neste caso, cada nó tem no mı́nimo um e no máximo três registros de
informação.
Neste caso, cada nó tem no mı́nimo dois e no máximo cinco registros de
informação.
50
125
7 15 40
17 50 83
3
5
20 35 48
60 70
203
51 80
85
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
150
205
Árvores do tipo B
1
187
2
3
5
10 12 13
20 21 25 30 32 45 46
55 56 57
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
61 62 63
Árvores do tipo B
71 72 75 76 80
188
Números mı́nimos e máximos de registros
Exemplos de inserção
Inserção de 81:
125
Árvore B de ordem 255:
17 50 83
mı́nimo
nı́vel
1
2
3
4
5
Total
nós
1
2
2 × 1281
2 × 1282
2 × 1283
4.227.331
máximo
nós
registros
1
1 × 255
2561
2561 × 255
2562
2562 × 255
3
256
2563 × 255
2564
2564 × 255
4.311.810.305 1.099.511.627.775
registros
1
2 × 127
2 × 1281 × 127
2 × 1282 × 127
2 × 1283 × 127
536.870.911
3
5
20 35 48
203
51 80
85
150
205
125
17 50 83
3
5
20 35 48
203
51 80 81
85
150
205
Neste caso, foi feita inserção numa folha com espaço disponı́vel. Houve h
leituras e uma gravação (h é a altura da árvore). O processo não se
propaga.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
189
Exemplos de inserção (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
190
Representação de árvores B
Inserção de 33:
125
#d e f i n e ORDEM 255
17 50 83
203
t y p e d e f s t r u c t NoArvB ∗ ArvB ;
3
20 35 48
5
51 80
85
150
205
t y p e d e f s t r u c t NoArvB {
i n t numregs ;
ArvB f i l h o s [ORDEM+ 1 ] ;
T i n f o [ORDEM ] ;
} NoArvBin ;
50 125
17 35
3
5
20 33
48
83
51 80
203
85
150
205
A capacidade de uma folha seria excedida e foi feita uma quebra que
propagou-se para cima. Haveria no máximo h leituras e 2h+1 gravações
(se a raiz também fosse quebrada).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
191
Esta representação será usada para simular árvores B na memória RAM.
Normalmente, árvores B são implementadas em memórias externas como
discos. O endereçamento em discos é usado em lugar de apontadores
comuns.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
192
Inserção em árvores B
Inserção em árvores B (cont.)
A explicação a seguir supõe que a inserção é realizada por uma função
recursiva auxiliar cujo cabeçalho é:
Explicação geral: caso de chamada recursiva sem propagação no retorno
B o o l e a n I n s e r e R e c A r v B ( ArvB ∗p , ArvB ∗ s , T ∗x , B o o l e a n ∗ p r o p ) ;
p
x
α
s
?
prop: ?
p
x
?
s
?
prop: false
onde
I
I
I
p: endereço da variável que contém o apontador para a árvore
prop: endereço da variável na qual é devolvida a informação que
indica se houve propagação de inserção no retorno
x: endereço de uma variável
I
I
numa chamada: contém o valor a ser inserido de algum tipo T
conveniente
no retorno, se houver propagação: contém o valor a ser propagado que
separa os valores das árvores apontadas por p e por s
s: endereço da variável que contém o apontador para a árvore
propagada (se houver)
I se não houver propagação numa chamada recursiva, o resto da árvore
não sofre mudança
O valor devolvido pela função indica se a inserção foi efetivamente
realizada ou se o elemento x já pertencia à arvore.
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
193
Inserção em árvores B (cont.)
α
Neste caso, não haverá mais modificações na árvore.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
194
Inserção em árvores B (cont.)
Explicação geral: caso de chamada recursiva com propagação no retorno
p
x
α
s
?
prop: ?
Caso 1: árvore vazia
p
x
<
α
x
α
s
p
x
α
s
?
prop: ?
prop: true
s
β
p
>
prop: true
Neste caso, são adotados valores das variáveis x, s e prop de maneira a
recair no caso geral de propagação.
α
Neste caso, a modificação deverá ser propagada para cima. O valor α da
variável x foi inserido numa das duas árvores (ou é o β). Se p apontava
para a raiz da árvore, será necessário criar uma nova raiz, com um único
valor β, e subárvores apontadas por p e s.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
195
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
196
Inserção em árvores B (cont.)
Inserção em árvores B (cont.)
Caso 2: inserção com espaço disponı́vel (r < b)
Caso 3: inserção sem espaço disponı́vel (r = b)
p
p
i−1
0
r −1
i
... xi−1 xi
0
b−1
i−1
b−1
i
... xi−1 xi
...
x
α
s
?
...
xb−1
x
α
s
?
prop: ?
prop: ?
Ti
(inserção recursiva em Ti )
Ti
(inserção recursiva em Ti )
p
i−1
0
r −1
i
... xi−1 xi
p
i−1
0
...
x
r
i
... xi−1 β
xi
b−1
...
x
s
?
?
Árvores do tipo B
197
b−1 b
i
xi
xb−1
...
x
?
s
?
prop: ?
x
?
s
?
prop: ?
(equivalente)
p
0
b−1 b
k
...
...
yk
yb
Tk Tk+1
p
0
k
yk−1
xb−1
x
β
prop: true
s
i−1
b−1 b
i
xi
...
xb−1
x
?
s
?
prop: ?
Neste caso, o valor propagado após a chamada recursiva não pode ser
absorvido pois o nó teria que ser aumentado além da capacidade máxima;
continua com quebra do nó (o espaço extra é apenas conceitual).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
198
Função de inserção auxiliar (esboço)
Caso 3: inserção sem espaço disponı́vel – quebra do nó
i−1
...
prop: false
Inserção em árvores B (cont.)
... xi−1 β
0
... xi−1 β
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
0
b−1
i
prop: true
s
β
Neste caso, o valor propagado após a chamada recursiva é absorvido no nó
corrente e a propagação pára.
p
i−1
... xi−1 xi
p
p
0
b−1
Tb+1
b−1
0
x yk
s
b−k
b−1
yk+1
prop: true
Tk
Tk+1
Tb+1
O nó corrente é quebrado em dois; o primeiro (nó original apontado por p)
retém k = db/2e+1 primeiros registros; o k-ésimo elemento e um novo nó
com b−k registros restantes são propagados de volta.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
199
B o o l e a n I n s e r e R e c A r v B ( ArvB ∗p , ArvB ∗ s , T ∗x , B o o l e a n ∗ p r o p ) {
int i ;
Boolean i n s e r i u ;
i f ( p==NULL) {
∗ p r o p = t r u e ; ∗ s = NULL ; r e t u r n t r u e ;
}
i = I n d i c e A r v B ( p , x ) ; // l o c a l i z a o p o n t o de i n s e r ç ã o
i f ( ( i <((∗ p)−>numregs ) ) && ( x==((∗p)−> i n f o ) [ i ] ) ) {
∗ prop = f a l s e ; return f a l s e ;
}
i n s e r i u = I n s e r e R e c A r v B (&((∗ p)−> f i l h o s [ i ] ) , s , x , p r o p ) ;
i f (∗ prop ) {
I n s e r e I n f o A r v B ( p , s , x , i ) } ; // i n s e r e ’ s ’ e ’ x ’ no nó
( ( ∗ p)−>numregs )++;
i f ( ( ( ∗ p)−>numregs<=ORDEM) )
∗ prop = f a l s e ;
else {
QuebraNoArvB ( p , s , x ) ; ∗ p r o p = t r u e ; // q u e b r a
}
}
return i n s e r i u ;
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
200
Função de inserção inicial
Exemplos de remoção
Remoção de 51:
125
B o o l e a n I n s e r e A r v B ( ArvB ∗p , T ∗ x ) {
/∗ D e v o l v e ’ f a l s e ’ s e o v a l o r de ’ x ’ j á o c o r r e na á r v o r e ’ p ’ ∗/
Boolean prop ;
ArvB q , s ;
B o o l e a n i n s e r i u = I n s e r e R e c A r v B ( p ,& s , x ,& p r o p ) ;
i f ( prop ) {
q = ( ArvB ) m a l l o c ( s i z e o f ( NoArvB ) ) ;
q−>numregs = 1 ;
( q−> f i l h o s ) [ 0 ] = ∗p ;
( q−> f i l h o s ) [ 1 ] = s ;
( q−>i n f o ) [ 0 ] = ∗ x ;
∗p = q ;
}
return i n s e r i u ;
}
O eventual aumento da altura da árvore se dará sempre nesta função.
17 50 83
3
5
20 35 48
203
51 80
85
150
205
125
17 50 83
3
5
20 35 48
203
80
85
150
205
Neste caso, foi feita remoção numa folha com número de registros acima
do mı́nimo. Houve h leituras e uma gravação (h é a altura da árvore). O
processo não se propaga.
Em todos os casos, a remoção deverá iniciar-se numa folha. Se necessário,
um elemento de um nó interno deverá ser substituı́do convenientemente.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
201
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplos de remoção (cont.)
Exemplos de remoção (cont.)
Remoção de 85:
Remoção de 150:
125
5
20 35 48
203
51 80
85
150
17 50 83
205
3
5
20 35 48
203
51 80
125
5
20 35 48
203
51
83
150
150
17 50
205
3
Neste caso, foi feita remoção numa folha com número mı́nimo de
registros, e foi feito um “empréstimo” de um nó irmão imediato com sobra
de registros. O empréstimo passa pelo nó pai a fim de manter a
propriedade de árvore de busca. Haveria no máximo h + 2 leituras e três
gravações. O processo não se propaga.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
85
205
83
17 50 80
3
202
125
17 50 83
3
Árvores do tipo B
Árvores do tipo B
203
5
20 35 48
125
51 80
85
203 205
Neste caso, foi feita remoção numa folha com número mı́nimo de registros
e cujos irmãos também estão no mı́nimo. Foi feita então uma junção de
dois nós e incluı́do o valor do nó pai que os separa. A remoção deste valor
do nó pai seguirá o mesmo esquema de remoções, e poderá se propagar
até a raiz. Haveria no máximo 3h − 2 leituras e 2h − 1 gravações.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
204
Observações
I
I
I
I
I
I
I
Variantes de árvores B
Verifica-se facilmente que tanto no caso de quebras (inserção) como
no caso de junções (remoção), os nós resultantes preservam as
propriedades de árvores B.
O número de leituras e gravações é sempre proporcional à altura da
árvore.
O nó raiz da árvore é normalmente guardado na memória, diminuindo
o número de acessos ao disco.
De acordo com a definição das árvores B, a utlização mı́nima do
espaço dos nós é de cerca de 50%; pode-se provar que a utilização
média é de cerca de 69%.
Usando técnicas probabilı́sticas, pode-se mostrar que as operações
mais complicadas são muito infrequentes.
A remoção pode ser implementada de maneira análoga à inserção e
será deixada para exercı́cio.
Uma árvore B inicial pode ser construı́da por inserções sucessivas o
que seria muito ineficiente; na prática, utiliza-se um algoritmo direto.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
205
I
Árvores B∗ : o número de registros ocupados de um nó é no mı́nimo
da sua capacidade.
I
Árvores B+ :
I
I
I
nós internos com chaves apenas para orientar o percurso
pares (chave, valor) apenas nas folhas
regra de descida:
I
I
I
I
subárvore esquerda: menor
subárvore direita: maior ou igual
apontadores em lugar de valores tornando mais eficiente a
movimentação dos registros durante inserções e remoções
ligações facilitando percurso em ordem de chaves
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
206
Variantes de árvores B (cont.)
Exemplo de árvore B+ de ordem 3:
23
4
6
8
11
15
11
12
Filas de prioridade
26
14
15
18
20
23
25
26
29
(Priority queues)
35
Setas tracejadas indicam apontadores para os valores da informação. A
lista ligada das folhas permite percurso simples e eficiente em ordem de
chaves.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores do tipo B
207
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Filas de prioridade
208
2
3
Definição e propriedades
I
Exemplo
Uma fila de prioridade é uma árvore binária com as propriedades:
I
I
a árvore é completa ou quase completa;
em cada nó da árvore, o valor da chave é maior ou igual aos valores
das chaves dos filhos (e consequentemente, de todos os descendentes).
I
Uma fila de prioridade não é uma árvore de busca!
I
A determinação do elemento máximo de uma fila de prioridade pode
ser feita em tempo constante (está na raiz).
I
As operações de inserção e de remoção podem ser realizadas em
tempo proporcional à altura (O(log n)).
I
I
95
0
88
1
75
2
30
3
45
4
15
7
10
8
40
5
38
6
23
9
Implementação sequencial (heap):
Filas de prioridade podem ser implementadas eficientemente de
maneira sequencial.
95
88
75
30
45
40
38
15
10
23
0
1
2
3
4
5
6
7
8
9
Em algumas aplicações é conveniente utilizar filas de prioridade em
que um elemento é menor ou igual a todos os seus descendentes.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Filas de prioridade
209
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Filas de prioridade
210
Operação de subida
Operação de descida
Supondo que, exceto pelo último elemento, a árvore é uma fila de
prioridade, a operação torna a árvore inteira uma fila válida.
Supondo que, exceto por um único valor que não é maior ou igual do que
seus descendentes, a árvore é uma fila de prioridade, a operação torna a
árvore inteira uma fila válida.
95
0
95
0
88
1
75
2
30
3
15
7
45
4
10
8
23
9
40
5
90
10
95
0
90
1
38
6
75
2
30
3
15
7
88
4
10
8
23
9
40
5
13
1
38
6
45
10
15
7
88
4
10
8
23
9
40
5
88
1
38
6
75
2
30
3
15
7
23
4
10
8
40
5
38
6
13
9
Setas duplas indicam as operações de troca a serem realizadas.
Obviamente, o número de operações de troca executadas é, no máximo,
igual à altura da árvore original (log2 n).
Filas de prioridade
75
2
30
3
Setas duplas indicam as operações de troca a serem realizadas.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
95
0
211
Obviamente, o número de operações de troca executadas é menor do que
a altura da árvore original (log2 n).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Filas de prioridade
212
Implementação das operações
#d e f i n e TAM MAX 50
typedef struct {
T v e t o r [TAM MAX ] ;
i n t tam ;
} Heap ;
Implementação das operações (cont.)
v o i d Sobe ( Heap ∗h , i n t m) {
i n t j = (m−1)/2;
T x = ( ∗ h ) . v e t o r [m ] ;
w h i l e ( (m>0) && ( ( ∗ h ) . v e t o r [ j ]< x ) ) {
( ∗ h ) . v e t o r [m] = ( ∗ h ) . v e t o r [ j ] ;
m = j;
j = ( j −1)/2;
}
( ∗ h ) . v e t o r [m] = x ;
} /∗ Sobe ∗/
Note-se que as operações de troca foram otimizadas com a utilização da
variável temporária x.
v o i d Desce ( Heap ∗h , i n t m) {
i n t k = 2∗m+1;
T x = ( ∗ h ) . v e t o r [m ] ;
w h i l e ( k <(∗h ) . tam ) {
i f ( ( k <((∗ h ) . tam ) −1) && ( ( ∗ h ) . v e t o r [ k ] <(∗ h ) . v e t o r [ k + 1 ] ) )
k++;
i f ( x <(∗h ) . v e t o r [ k ] ) {
( ∗ h ) . v e t o r [m] = ( ∗ h ) . v e t o r [ k ] ;
m = k;
k = 2∗ k +1;
} else
break ;
}
( ∗ h ) . v e t o r [m] = x ;
} /∗ Desce ∗/
Também neste caso, as operações de troca foram otimizadas.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Filas de prioridade
213
Construção inicial
Filas de prioridade
214
Inserção e remoção
Dado um vetor com elementos em ordem arbitrária, deve-se transformá-lo
numa fila de prioridade:
v o i d C o n s t r o i H e a p 1 ( Heap ∗h ) {
int i ;
f o r ( i =1; i <(∗h ) . tam ; i ++)
Sobe ( h , i ) ;
} /∗ C o n s t r o i H e a p 1 ∗/
Note-se que a função RemoveHeap remove e devolve na variável x o
elemento máximo da fila. Obviamente, as duas funções realizam no
máximo O(n log n) operações.
Verifica-se facilmente que a eficiência da função ConstroiHeap1 é
O(n log n). Pode-se demonstrar, também, que a eficiência de
ConstroiHeap2 é O(n) (linear).
Filas de prioridade
v o i d I n s e r e H e a p ( Heap ∗h , T x ) {
v e t o r [ ( ∗ h ) . tam ] = x ;
( ( ∗ h ) . tam)++;
Sobe ( h , ( ( ∗ h ) . tam ) −1);
} /∗ I n s e r e H e a p ∗/
v o i d RemoveHeap ( Heap ∗h , T ∗ x ) {
∗x = (∗ h ) . v e t o r [ 0 ] ;
( ( ∗ h ) . tam)−−;
(∗ h ) . v e t o r [ 0 ] =
( ∗ h ) . v e t o r [ ( ∗ h ) . tam ] ;
Desce ( h , 0 ) ;
} /∗ RemoveHeap ∗/
v o i d C o n s t r o i H e a p 2 ( Heap ∗h ) {
int i ;
f o r ( i =((∗ h ) . tam −2)/2; i >=0; i −−)
Desce ( h , i ) ;
} /∗ C o n s t r o i H e a p 2 ∗/
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
215
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Filas de prioridade
216
Algoritmo de ordenação Heapsort
O algoritmo constrói um heap inicial. Em seguida, remove um a um o
elemento máximo e o coloca na posição final do vetor.
v o i d H e a p S o r t ( Heap ∗h ) {
i n t i , n = ( ∗ h ) . tam ;
/∗ c o n s t r ó i heap ∗/
f o r ( i =(n −2)/2; i >=0; i −−)
Desce ( h , i ) ;
/∗ o r d e n a ∗/
f o r ( i=n −1; i >0; i −−) {
T t = (∗ h ) . v e t o r [ 0 ] ;
(∗ h ) . v e t o r [ 0 ] = (∗ h ) . v e t o r [ i ] ;
(∗ h ) . v e t o r [ i ] = t ;
( ∗ h ) . tam−−;
Desce ( h , 0 ) ;
}
( ∗ h ) . tam = n ;
} /∗ H e a p S o r t ∗/
Árvores gerais
Número de operações: O(n log n) (um dos algoritmos ótimos).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Filas de prioridade
217
Exemplo de árvore geral
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores gerais
218
Representação de árvores gerais
A
B
F
C
G
H
D
#d e f i n e GRAU MAX 10
typedef struct
NoArvGeral ∗ ArvGeral ;
typedef s t r u c t NoArvGeral {
T info ;
i n t grau ;
A r v G e r a l f i l h o s [ GRAU MAX ] ;
} NoArvGeral ;
E
I
J
K
L
I
árvores gerais nunca são vazias
I
as subárvores são ordenadas: primeira, segunda, etc
I
o número de subárvores pode ser qualquer, inclusive zero
I
conceitos naturais: grau, filhos, pai, descendente, altura, etc
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores gerais
...
...
p = malloc ( s i z e o f ( NoArvGeral ) ) ;
p = m a l l o c ( s i z e o f ( N o A r v G e r a l )+
( grau −1)∗ s i z e o f ( A r v G e r a l ) ) ;
...
...
219
typedef struct
NoArvGeral ∗ ArvGeral ;
typedef s t r u c t NoArvGeral {
T info ;
i n t grau ;
ArvGeral f i l h o s [ 1 ] ;
} NoArvGeral ;
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores gerais
220
Florestas
Floresta representada como árvore binária
Uma floresta é uma sequência, possivelmente vazia, de árvores gerais.
A
B
C
Exemplo:
D
A
D
J
E
K
B
F
L
G
M
J
C
H
E
K
F
L
G
H
M
I
N
O
Q
I
N
O
P
P
Q
I
o campo esquerdo aponta para a raiz da primeira subárvore original
I
o campo direito aponta para o nó irmão seguinte
I
as raı́zes das árvores da floresta são consideradas irmãs.
Note-se que as subárvores de um nó de uma árvore geral constituem uma
floresta.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores gerais
221
Floresta representada como árvore binária (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores gerais
222
Percursos em profundidade de florestas
Os percursos de uma floresta F = (T1 , T2 , . . . , Tm ) são definidos por:
I
A árvore binária B(F ) que representa uma floresta
F = (T1 , T2 , . . . , Tm ) é definida por:
I
I
árvore binária vazia se F é uma floresta vazia (m = 0);
árvore binária cuja raiz contém a mesma informação da raiz de T1 ; cuja
subárvore esquerda é dada por B((T11 , T12 , . . . , T1m1 )) onde
(T11 , T12 , . . . , T1m1 ) é a floresta das subárvores de T1 ; e cuja subárvore
direita é dada por B((T2 , . . . , Tm )).
I
Conclui-se facilmente que toda floresta tem uma única representação
binária.
I
A implementação de árvores binárias é mais simples.
I
Exercı́cio: definir a transformação contrária F(T ) que obtém a
floresta a partir da árvore binária T que a representa.
I
Exercı́cio: verificar se toda árvore binária representa uma floresta.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores gerais
223
I
Pré-ordem de florestas:
Visitar a raiz de T1
Percorrer a floresta F1 em pré-ordem de florestas
Percorrer a floresta (T2 , . . . , Tm ) em pré-ordem de
florestas
I
Pós-ordem de florestas:
Percorrer a floresta F1 em pós-ordem de florestas
Percorrer a floresta (T2 , . . . , Tm ) em pós-ordem de
florestas
Visitar a raiz de T1
I
Inordem de florestas:
Percorrer a floresta F1 em inordem de florestas
Visitar a raiz de T1
Percorrer a floresta (T2 , . . . , Tm ) em inordem de florestas
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores gerais
224
Percursos em profundidade de florestas (cont.)
A
B
Percursos em profundidade de florestas (cont.)
C
Propriedades:
D
J
E
K
F
L
G
M
H
I
N
O
P
I
percurso de uma floresta F produz o mesmo resultado que o percurso
(binário) correspondente da árvore B(F ).
I
pré-ordem de florestas é semelhante à pré-ordem de árvores binárias
I
inordem de florestas é semelhante à pós-ordem de árvores binárias
I
pós-ordem de florestas não tem uma interpretação natural
Q
Desafio:
Pré-ordem: A,D,J,E,K,L,F ,G,M ,B,C,H,I,N ,O,Q,P
Elabore um algoritmo para percurso em largura de árvores gerais sob
representação binária.
Pós-ordem: J,L,K,M ,G,F ,E,D,Q,P ,O,N ,I,H,C,B,A
Inordem: J,D,K,L,E,F ,M ,G,A,B,H,N ,Q,O,P ,I,C
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores gerais
225
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores gerais
226
Árvores digitais
228
Conjuntos de cadeias de caracteres
Exemplo:
Árvores digitais
a
an
and
are
as
(Tries)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores digitais
227
at
be
but
by
for
from
had
have
he
her
his
i
in
is
it
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
no
not
of
on
or
a
an
and
are
as
Árvore digital
a
b
f
n
i
h
at
be
but
by
for
from
had
have
he
her
his
i
in
is
it
no
not
of
on
or
Implementação de árvores digitais
o
a
b
y
c
z
...
n
r
s
e
t
e
d
u y
o r
r
t
a
o
e
d v
m
n
i
r
s
o
t
s
f
n r
t
I
I
e
Algoritmos de busca, inserção e remoção óbvios (exercı́cio).
Uso de memória:
I
Arestas são rotuladas com as letras das palavras.
Nós cheios indicam o fim de uma cadeia.
São fatorados os prefixos comuns das cadeias.
Números para o exemplo:
I
I
I
I
I
I
I
I
39
20
19
25
I
I
I
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores digitais
Árvore digital com subcadeias
Eliminando apontadores das folhas:
I
nós
folhas
nós internos (não folhas)
nós cheios (25 palavras)
a
an
and
are
as
at
be
but
by
for
from
had
have
he
her
19 × 26 = 494 campos apontadores
38 campos são não nulos
Existem alternativas mais econômicas para representar os nós.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
229
his
i
in
is
it
39 × 26 = 1014 campos apontadores
38 campos são não nulos
Árvores digitais
Autômato finito minimal acı́clico
no
not
of
on
or
Exemplo: as 15 formas dos verbos ingleses: do, redo e undo
d
d
a
b
f
n
i
h
230
do
does
did
doing
done
o
redo
redoes
redid
redoing
redone
undo
undoes
undid
undoing
undone
r
e
u
n
s
d
i
e
o
i
g
n
n
e
n
r
s
re
e
t
s
s
e
u y
ut
o r
y
or
a
d
n
i
rom
is
d v
d
e
d
r
ve r
n
s
t
s
o
f
t
f
n r
n
r
I
I
t
I
t
I
São fatorados tanto os prefixos quanto os sufixos comuns das cadeias.
Algoritmo de busca igual ao de árvores digitais.
Algoritmos de inserção e de remoção muito mais complicados.
Uso de memória:
I
I
I
Uso de memória:
I
I
I
12 × 26 = 312 campos apontadores
31 campos são não nulos
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Se fosse árvore digital:
I
I
I
Árvores digitais
231
11 × 26 = 286 campos apontadores (nós internos)
16 campos são não nulos
26 × 26 = 676 campos apontadores (nós internos)
37 campos seriam não nulos
As estruturas para um exemplo análogo em português seriam maiores
(mais de 50 formas verbais) mas resultariam em muito mais economia.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Árvores digitais
232
Conceito e exemplos
I
I
Um átomo é um inteiro ou uma cadeia de caracteres.
Uma lista generalizada é uma sequência:
(α1 , α2 , . . . , αn )
Listas generalizadas
I
I
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Listas generalizadas
233
Expansão de listas
onde αi denota um átomo ou uma lista generalizada (definição
recursiva).
Exemplos de listas:
A: ((4,7),(4,7,(8)))
B: ((1,4),(7,8))
C: (3,B,B)
D: (5,8,D)
E: ()
As listas A, B, C, D e E têm, respectivamente, 2, 2, 3, 3 e 0
elementos.
A definição de átomo poderia ser estendida para outros tipos de
valores.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Implementação compartilhada
A:
B:
C:
D:
E:
((4,7),(4,7,(8)))
((1,4),(7,8))
(3,B,B)
(5,8,D)
()
A:
4
4
Listas generalizadas
A:
B:
C:
D:
E:
234
((4,7),(4,7,(8)))
((1,4),(7,8))
(3,B,B)
(5,8,D)
()
7
7
8
As listas C e D podem ser expandidas com as definições correspondentes:
B:
C: (3,((1,4),(7,8)),((1,4),(7,8)))
D: (5,8,(5,8,(5,8,(...))))
1
A lista D tem três elementos, mas inclui um número infinito de inteiros,
por ser recursiva.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
7
Listas generalizadas
235
C:
3
D:
5
E:
NULL
8
4
8
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Listas generalizadas
236
A:
B:
C:
D:
E:
Implementação com cópia
((4,7),(4,7,(8)))
((1,4),(7,8))
(3,B,B)
(5,8,D)
()
Representação de listas generalizadas
3
7
B:
1
C:
7
1
5
8
4
7
1
4
5
8
8
4
typedef struct RegListaGen ∗ ListaGen ;
8
typedef struct RegListaGen {
ListaGen prox ;
B o o l e a n eAtomo ;
union {
i n t atomo ;
/∗ ’ eAtomo ’ v e r d a d e i r o ∗/
ListaGen l i s t a ;
/∗ ’ eAtomo ’ f a l s o ∗/
} info ;
} RegListaGen ;
8
5
8
D:
...
I
Não é possı́vel completar a expansão da lista D.
I
As representações das listas A, B e E não mudam.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Listas generalizadas
237
Exemplo de manipulação
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Listas generalizadas
238
Representação alternativa
Função de contagem de átomos:
i n t ContaAtomos ( L i s t a G e n p ) {
int s = 0;
w h i l e ( p!=NULL) {
i f ( p−>eAtomo )
s ++;
else
s += ContaAtomos ( p−>i n f o . l i s t a ) ;
p = p−>p r o x ;
}
return s ;
} /∗ ContaAtomos ∗/
typedef struct RegListaGen ∗ ListaGen ;
typedef struct RegListaGen {
B o o l e a n v i s i t a d o ; /∗ i n i c i a l m e n t e f a l s o ∗/
ListaGen prox ;
B o o l e a n eAtomo ;
union {
i n t atomo ;
/∗ ’ eAtomo ’ v e r d a d e i r o ∗/
L i s t a G e n l i s t a ; /∗ ’ eAtomo ’ f a l s o ∗/
} info ;
} RegListaGen ;
Problemas com compartilhamento:
I
contagem repetida (caso da lista C ); pode ser intencional
I
repetição infinita (caso da lista D)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Listas generalizadas
239
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Listas generalizadas
240
Exemplo de manipulação
Exemplo de aplicação
Função geral de contagem de átomos:
Manipulação de polinômios em múltiplas variáveis:
P (x, y, z) = x10 y 3 z 2 + 2x8 y 3 z 2 + 3x8 y 2 z 2 + x4 y 4 z − 6x3 y 4 z + 2yz
i n t ContaAtomos ( L i s t a G e n p ) {
int s = 0;
w h i l e ( ( p!=NULL) && ! ( p−>v i s i t a d o ) ) {
p−>v i s i t a d o = t r u e ;
i f ( p−>eAtomo )
s ++;
else
s += ContaAtomos ( p−>i n f o . l i s t a ) ;
p = p−>p r o x ;
}
return s ;
} /∗ ContaAtomos ∗/
Representação possı́vel para cada termo:
coef
Problema: restauração dos valores do campo visitado para o próximo
percurso.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Representação de polinômios
Listas generalizadas
y
x
I
Problema: muito inflexı́vel, somente para polinômios em três variáveis.
I
Alternativa: um polinômio em k ≥ 1 variáveis pode ser considerado
um polinômio em uma variável, com coeficientes que são polinômios
em k−1 variáveis, etc:
P (x, y, z) = ((x10 + 2x8 )y 3 + 3x8 y 2 )z 2 + ((x4 − 6x3 )y 4 + 2x0 y)z
241
((x10 + 2x8 )y 3 + 3x8 y 2 )z 2 + ((x4 − 6x3 )y 4 + 2x0 y)z
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Alternativa 2: representação que elimina polinômios “degenerados”
z
y
4
2
1
1
y
x
x
1
4
2
3
x
−6 3
y
x
1
4
x
3
8
10
2
8
2
1
x
3
8
10
2
8
2
4
0
x
y
242
((x10 + 2x8 )y 3 + 3x8 y 2 )z 2 + ((x4 − 6x3 )y 4 + 2x0 y)z
1
2
Listas generalizadas
Representação de polinômios (cont.)
Alternativa 1: representação uniforme em todos os nı́veis:
z
z
3
x
1
2
0
−6 3
2
1
2x0 y
Note-se que o termo
é representado de maneira completa. Esta
representação torna os algoritmos mais simples.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Listas generalizadas
Note-se que o termo 2x0 y é representado como 2y. Esta representação
economiza memória (retângulo tracejado).
243
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Listas generalizadas
244
Declaração de tipo
LISP: uma linguagem para processamento de listas
t y p e d e f s t r u c t Termo ∗ApTermo ;
t y p e d e f ApTermo P o l i n o m i o ;
t y p e d e f s t r u c t Termo {
Polinomio prox ;
B o o l e a n eCabeca ;
union {
char v a r i a v e l ;
/∗ s e é c a b e ç a ∗/
struct {
/∗ s e é termo ∗/
int expoente ;
Boolean c o e f I n t e i r o ;
union {
int coefInt ;
Polinomio coefPolin ;
} coef ;
} termo ;
} no ;
} Termo ;
I
Programas são expressos como listas.
I
Dados são átomos e listas.
Aplicações:
I
I
I
I
I
inteligência artificial
scripts para Emacs
scripts para AutoCAD
...
Exercı́cio: escrever as funções de soma e de multiplicação para polinômios
em múltiplas variáveis.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Listas generalizadas
245
LISP (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Listas generalizadas
246
LISP (cont.)
Exemplo 2: concatenação e inversão de listas
( defun c o n c a t ( p q )
( cond ( n u l l p )
q
( cons ( c a r p ) ( c o n c a t ( c d r p ) q ) )
)
)
Exemplo 1: função fatorial
( defun f a t o r i a l ( n )
( cond ( l e q n 1 )
1
( mult n ( f a t o r i a l ( minus n 1 ) ) )
)
)
( defun i n v e r t e ( p )
( cond ( n u l l p )
nil
( concat ( i n v e r t e ( cdr p )) ( car p ))
)
)
I
A expressão: (fatorial 5) produz: 120.
I
Deve-se notar o uso de notação pré-fixa.
I
As implementações comuns de LISP permitem o uso de sı́mbolos de
operações como <=, + e ∗ em lugar de átomos.
I
I
I
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Listas generalizadas
247
A expressão: (inverte ’(A B C D)) produz D C B A.
A expressão (car L) devolve o primeiro elemento da lista L.
A expressão (cdr L) devolve a lista L sem o primeiro elemento.
A operação (cons x L) devolve a lista L com o elemento x inserido
na frente da lista.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Listas generalizadas
248
Tabelas de espalhamento
Exemplo de tabela com b = 7 linhas e s = 3 colunas:
1
Espalhamento
f (’jo~
ao’) →
(Hashing ou scattering)
0
1
2
3
4
5
6
2
3
jo~
ao
Supõe-se, neste caso, que:
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
249
Tabelas de espalhamento (cont.)
I
a função de espalhamento f produz resultados entre 0 e 6
I
f (’jo~
ao’) = 3
I
existem no máximo três valores (s) a serem inseridos que produzem o
mesmo valor da função f .
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
250
Virtudes e poblemas
Exemplo de tabela com b = 26 linhas e s = 2 colunas:
0
1
2
3
4
5
1
ant^
onio
2
átila
I
I
carlos
douglas
ernesto
I
célio
est^
ev~
ao
I
simplicidade
busca muito rápida (se a função de espalhamento for eficiente)
Problemas
I
···
24
25
Virtudes
I
I
escolha da função de espalhamento
tratamento de colisões
tratamento de estouro da tabela
zoroastro
Foi usada uma função (muito ingênua!) de espalhamento: ı́ndice da
primeira letra (a: 0, b: 1, ...).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
251
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
252
Construção de funções de espalhamento
Construção de funções de espalhamento (cont.)
Divisão
I
O nome, tratado como um número na base 26, é dividido por um
número p relativamente primo f (x) = x mod p; p será adotado como
o número de linhas da tabela.
I
Para p = 51 terı́amos:
Propriedades desejáveis:
I
I
I
I
eficiência de cálculo
bom espalhamento
Técnicas:
I
I
f (carlos) = ( ((((2 × 26 + 0) × 26 + 17) × 26 + 11)
espalhamento mı́nimo perfeito
espalhamento pseudo-aleatório: combinação de várias técnicas
×26 + 14) × 26 + 18 ) mod 51
= 24.069.362 mod 51 = 14
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
253
Construção de funções de espalhamento (cont.)
Na realidade, o cálculo pode ser simplificado, com a operação mod
aplicada a cada passo.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
254
Construção de funções de espalhamento (cont.)
Dobramento (folding)
Seleção de algarismos e meio-do-quadrado
I
O nome é tratado como uma sequência de algarismos ou de bytes ou
de bits, e uma subsequência é selecionada para representar o ı́ndice.
I
Por exemplo, suponhamos que todos os nomes são representados
como a sequência de dı́gitos x = d0 d1 · · · d11 em alguma base
conveniente; uma escolha seria f (x) = d3 d5 d9 .
I
Exemplo: a representação de ‘carlos’ poderia ser 020017111418.
Supusemos que cada letra é indicada por dois dı́gitos que indicam a
posição no alfabeto, ou seja 00 para ‘a’, 01 para ‘b’, etc. Terı́amos
então f (carlos) = 074.
I
Frequentemente, antes de fazer a seleção, é calculado o quadrado do
identificador (tratado como número); é o método
“meio-do-quadrado” (mid-square).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
255
I
O nome é tratado como uma sequência de algarismos ou de bytes ou
de bits, e algumas subsequências são combinadas por operações
convenientes para produzir um ı́ndice.
I
Por exemplo, suponhamos que todos os nomes são representados
como uma sequência de bits x = b0 b1 b2 b3 b4 · · · ; uma escolha seria:
f (x) = b0 b1 b2 b3 b4 b5 ⊕ b6 b7 b8 b9 b10 b11 ⊕ · · ·
onde ⊕ denota a operação de ou exclusivo bit a bit.
I
Exemplo: a representação de ‘carlos’ usada anteriormente poderia
ser (com cinco bits para cada número):
00010 00000 10001 01011 01110 10010
produzindo a sequencia de bits: 000100000010001010110111010010 e
o resultado:
f (000100000010001010110111010010) =
000100 ⊕ 000010 ⊕ 001010 ⊕ 110111 ⊕ 010010 = 101001 = 4110
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
256
Tratamento de colisões: endereçamento aberto
Reespalhamento linear
ant^
onio, carlos, douglas, célio, armando, zoroastro, átila, alfredo
Usando (f (x) + i) mod b, (i = 0, 1, · · · ), procura a primeira posição livre.
I
Busca sistemática de outras entradas disponı́veis na tabela:
I
I
I
0
1
2
3
4
5
6
7
···
25
reespalhamento linear
reespalhamento quadrático
reespalhamento duplo
I
Em todos os casos, os algoritmos de busca, inserção e remoção
deverão ser coerentes.
I
Exemplos usam: ant^
onio, carlos, douglas, célio, armando,
zoroastro, átila, alfredo (nesta ordem).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
257
ant^
onio
armando
carlos
douglas
célio
átila
alfredo
···
zoroastro
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
258
Reespalhamento quadrático
Reespalhamento duplo
ant^
onio, carlos, douglas, célio, armando, zoroastro, átila, alfredo
ant^
onio, carlos, douglas, célio, armando, zoroastro, átila, alfredo
Usando (f (x) + i2 ) mod b, (i = 0, 1, · · · ), procura a primeira posição livre.
I
0
1
2
3
4
5
6
7
8
9
···
25
ant^
onio
armando
carlos
douglas
átila
I
célio
alfredo
···
zoroastro
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
259
Usando (f (x) + i × g(x)) mod b, (i = 0, 1, · · · ) procura a primeira
posição livre.
0
ant^
onio
g(x) é a função de reespalhamento;
1
por exemplo, g(x) = (c mod 3) + 1
2
carlos
onde c é a segunda letra.
3
douglas
4
célio
5
6
armando
7
8
átila
9
alfredo
···
···
25 zoroastro
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
260
Remoção
I
Lápides (tombstones):
I
I
I
Eficiência com endereçamento aberto
entradas que indicam posições ocupadas para fins de busca, mas livres
para fins de inserção.
podem ser usadas com qualquer esquema de espalhamento
I
C(n) = (2 − α)/(2 − 2α)
onde:
Exemplo: remoção da entrada armando (tabela com reespalhamento
linear):
0
1
2
3
4
5
6
7
···
25
ant^
onio
armando
carlos
douglas
célio
átila
alfredo
···
zoroastro
0
1
2
3
4
5
6
7
···
25
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Número médio de comparações para encontrar um elemento:
I
I
I
ant^
onio
++++++++
carlos
douglas
célio
átila
alfredo
I
Exemplo de tabela com 1000 entradas:
···
zoroastro
Espalhamento
261
Tratamento de colisões: listas ligadas
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
I
armando
antônio
antônio
I
I
carlos
célio
douglas
3
carlos
I
5
...
zoroastro
As listas poderiam ser ordenadas.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
α = n/b (fator de carga, α > 0)
n é o número de entradas
b é o tamanho da tabela
Exemplo de tabela com 1000 entradas:
n
100
200
400
500
1000
2000
4
25
262
onde:
1
2
Espalhamento
Número médio de comparações para encontrar um elemento:
I
armando
antônio
átila
C(n)
1,06
1,13
1,21
1,33
1,50
1,75
2,17
3,00
5,50
10,5
C(n) = 1 + α/2
Exemplo:
ant^
onio, carlos, douglas, célio, armando, zoroastro, átila, alfredo
armando
antônio
alfredo
átila
n
100
200
300
400
500
600
700
800
900
950
Eficiência com encadeamento
Técnica de encadeamento (chaining): utiliza listas ligadas para manter
entradas com o mesmo valor da função de espalhamento.
0
α = n/b (fator de carga, 0 ≤ α ≤ 1)
n é o número de entradas
b é o tamanho da tabela
Espalhamento
263
C(n)
1,05
1,10
1,20
1,25
1,50
2,00
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Espalhamento
264
Compressão de textos
I
I
Compressão de textos
I
(Codificação de Huffman)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Objetivos:
Compressão de textos
265
economia de espaço
velocidade de transmissão
I
Representação normal: um byte (8 bits) por caractere (alfabetos
“comuns”)
I
Compressão por contagem (run-length encoding)
I
Codificação de Huffman
I
Algoritmos de codificação aritmética (Lempel-Ziv – zip, gzip, winzip,
et.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Compressão de textos
266
Árvores binárias de codificação
Codificação de Huffman
Codificação fixa
a: 000
b: 001
c: 010
d: 011
e: 100
f: 101
100
I
Explora frequências de ocorrência de caracteres
I
Exemplo de alfabeto: A = {a, b, c, d, e, f }
frequência de cada letra
codificação usando 3 bits
codificação de tamanho variável
I
a
45
000
0
b
13
001
101
0
86
c
12
010
100
d
16
011
111
e
9
100
1101
f
5
101
1100
Para um arquivo de 100.000 caracteres:
I
I
codificação fixa: 300.000 bits
codificação variável: 224.000 bits (economia de 25%)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
1
Compressão de textos
267
14
0
1
1
0
58
0
a:45
0
28
b:13
c:12
14
1
d:16
0
e:9
1
f:5
I
Os rótulos das arestas da raiz até uma folha compõem o código da
letra correspondente.
I
Para obter o código de uma letra, é necessário percorrer a árvore
partindo da folha correspondente até a raiz.
I
Exemplo: abc = 000k001k010 = 000001010.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Compressão de textos
268
Árvores binárias de codificação (cont.)
Codificação variável
a: 0
b: 101
c: 100
Construção da árvore de Huffman
d: 111
e: 1101
f: 1100
I
100
0
1. Construa uma floresta de folhas, cada uma correspondendo a um
caractere, com a respectiva frequência como seu peso.
2. Enquanto a floresta tiver mais de uma árvore, repita:
1
a:45
55
0
1
25
0
Algoritmo (guloso):
I
I
30
1
0
1
I
c:12
14
b:13
0
d:16
1
I
A solução não é única (pode haver várias escolhas de peso mı́nimo),
mas todos os resultados são equivalentes quanto à eficiência de
compressão.
I
Se o alfabeto for razoavelmente grande, pode-se utilizar uma fila de
prioridade para selecionar, em cada passo, duas árvores de menor
peso.
e:9
f:5
procure na floresta duas árvores t1 e t2 de menor peso
construa uma nova árvore binária t, com subárvores t1 e t2 , e com peso
que é a soma dos pesos das duas subárvores
remova t1 e t2 da floresta, e insira t.
I
O código de uma letra não pode constituir um prefixo de uma outra
letra.
I
Exemplo: abc = 0k101k100 = 0101100.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Compressão de textos
269
Construção da árvore de Huffman (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Compressão de textos
270
Construção da árvore de Huffman (cont.)
Exemplo:
a:45
c:12
b:13
e:9
d:16
a:45
f:5
14
d:16
f:5
a:45
b:13
c:12
a:45
e:9
14
b:13
30
14
b:13
d:16
25
f:5
f:5
c:12
25
c:12
d:16
e:9
14
d:16
f:5
a:45
25
e:9
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
c:12
e:9
b:13
Compressão de textos
271
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Compressão de textos
272
Construção da árvore de Huffman (cont.)
a:45
25
c:12
Construção da árvore de Huffman (cont.)
30
14
b:13
d:16
a:45
100
55
0
f:5
25
c:12
a:45
1
e:9
a:45
30
14
b:13
55
0
f:5
25
e:9
1
1
0
25
d:16
55
0
c:12
30
14
b:13
0
30
f:5
c:12
14
b:13
f:5
1
d:16
1
e:9
d:16
e:9
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Compressão de textos
273
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Compressão de textos
274
Observações
I
Adotadas certas hipóteses, demonstra-se a otimalidade de compressão
I
Algoritmo de compressão: para cada letra, deve acessar a folha
correspondente da árvore e reconstruir o caminho à raiz – pode ser
preprocessado
I
Algoritmo de descompressão: percorre a árvore a partir da raiz
seguindo o caminho indicado por bits da codificação
Variantes:
I
I
I
I
Gerenciamento de memória
árvore fixa, por exemplo, uma para cada lı́ngua
árvore por texto (acompanha o arquivo)
árvores dinâmicas (Faller, Gallager e Knuth).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Compressão de textos
275
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
276
Gerenciamento de memória
Gerenciamento explı́cito
Configuração genérica da memória:
Vários aspectos:
disp
I
alocação com e sem disciplina de pilha
I
caracterı́sticas da linguagem de programação
I
registros de tamanho fixo ou variável
I
gerenciamento explı́cito (malloc e free)
I
gerenciamento implı́cito (coleta de lixo e contagem de referências)
I
gerenciamento misto
Livre:
m
M
disp
I
I
I
Gerenciamento de memória
277
A variável disp (memória disponı́vel) é global.
A lista das áreas livres é ordenada pelo valor dos apontadores.
M denota o tamanho da área livre inicial; m de uma área livre ou em
uso.
A função de alocação devolve o apontador para o primeiro byte livre
da área.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento explı́cito (cont.)
Gerenciamento explı́cito (cont.)
Uma versão muito simples de malloc(n) (f é o tamanho da parte fixa de
cada área – apontador mais o campo de tamanho):
Uma versão muito simples de free(p):
1. procure na lista disp o primeiro elemento (ou o elemento de tamanho
mı́nimo) p com tamanho≥ n+f
2. remova p da lista disp
3. quebre a área apontada por p em duas partes: uma p1 de tamanho
n + f e outra p2 com o que sobrar (se houver sobra suficiente)
4. insira p2 na lista disp (se existir)
Gerenciamento de memória
278
1. procure na lista disp o ponto de inserção para p (ordem crescente dos
apontadores)
2. verifique se o predecessor e/ou sucessor de p neste ponto são
adjacentes à área apontada por p
3. se for possı́vel, junte a área liberada à predecessora e/ou à sucessora,
modificando os campos de tamanho
4. atualize a lista
5. devolva p1 + f
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
?
Configuração inicial:
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Em uso:
m
Gerenciamento de memória
279
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
280
Gerenciamento explı́cito (cont.)
Marcas de fronteira
Livre:
Problemas:
Em uso:
t
m
t
f
m
f
I
O que fazer quando malloc não acha uma área de tamano suficiente –
requer outra área ao sistema operacional
I
Fragmentação – após várias alocações e liberações, com tamanhos
variáveis, haverá tendência a produzir muitas área livres pequenas
I
As áreas livres constituem uma lista duplamente ligada.
I
m denota o tamanho da área.
I
Busca numa lista ligada pode ser ineficiente
Algumas soluções:
I
t e f denotam os valores booleanos que indicam se a área é livre.
I
A função de alocação devolve o apontador para o primeiro byte livre
da área.
I
Não é necessário fazer uma busca na lista para encontrar as áreas
vizinhas.
I
Exercı́cio: esboçar a implementação das funções malloc e free.
I
I
I
blocos com marcas de fronteira (boundary tags)
sistema de blocos conjugados (buddy system)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
281
Sistema de blocos conjugados
I
8-15
0-1
k=3
0-3
k=2
4-7
0-1
k=1
2-3
6-7
8-9
12-15
10-11
12-13
Em uso:
I
k=0
0
I
I
I
I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Uma árvore binária imaginária em que cada nó representa um bloco
de alocação.
Cada folha da árvore representa um bloco mı́nimo de alocação.
Cada nı́vel k da árvore (a partir das folhas) representa a alocação de
uma área constituı́da de 2k blocos mı́nimos.
Áreas conjugadas (irmãs) facilmente reconhecidos pelos ı́ndices sob
forma binária.
O exemplo exibe a árvore para uma memória de 24 = 16 blocos.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
t
k
f
k
14-15
I
I
282
Formato das áreas:
Livre:
8-11
4-5
Gerenciamento de memória
Sistema de blocos conjugados (cont.)
0-15
k=4
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
283
I
I
I
t e f denotam os valores booleanos que indicam se a área é livre.
k indica que o tamanho da área é 2k .
Para cada valor de k, existe uma lista duplamente ligada disp[k] de
blocos livres de tamanho 2k .
A função de alocação devolve o apontador para o primeiro byte livre
da área.
Dado o número do bloco inicial de uma área (em binário) de tamanho
2k , o número da área conjugada é determinado complementando o
k-ésimo bit (a partir da direita); exemplo de bloco 12 para k = 2:
1210 = 11002 =⇒ 10002 = 810
Portanto, a área conjugada de quatro blocos tem inı́cio no bloco 8.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
284
Sistema de blocos conjugados (cont.)
Sistema de blocos conjugados (cont.)
Esboço da função malloc(n) (f é o tamanho da parte fixa de cada área –
marca de uso, tamanho):
Esboço da função free(p):
1. procure um k tal que 2k ≥ n + f , e a lista de blocos para k não está
vazia; remova desta lista uma área p
2. se 2k−1 ≥ n + f , quebre a área p em duas (conjugadas), acerte os
tamanhos e insira uma delas na lista de áreas para tamanho k − 1
1. seja k o expoente correspondente ao tamanho de p
2. calcule o endereço da área q conjugada de p
3. se a área q está livre:
I
I
3. repita o passo anterior para k − 2, k − 3, ..., enquanto possı́vel
I
I
4. devolva o apontador p + f
Note-se que o desperdı́cio de memória de uma área pode chegar a quase
50%.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
285
Sistema de blocos conjugados (cont.)
remova q da lista disp[k]
junte as áreas p e q para formar uma nova área livre p
faça k = k+1
volte ao passo inicial
4. se a área q não está livre (ou não existe – p já é a memória inteira),
insira p na lista disp[k]
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
286
Gerenciamento implı́cito
Uma outra alternativa é utilizar os números de Fibonacci:
0-12
Coleta de lixo (garbage collection)
F7 = 13
F6 = 8
I
0-7
Caracterı́sticas:
I
F5 = 5
I
8-12
0-4
I
F4 = 3
0-2
5-7
8-10
I
I
F3 = 2
0-1
3-4
5-6
8-9
11-12
I
Fases:
I
I
F2 = 1
0
I
I
1
2
3
4
5
6
7
8
9
10
11
12
Esta solução diminui o desperdı́cio de memória, mas torna mais
complicados os algoritmos.
Exercı́cio: esboçar as funções malloc e free para esta alternativa.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
287
operação de alocação implı́cita em algumas operações
não existe operação de liberação explı́cita ou é opcional
liberação de memória realizada, em geral, quando não há mais espaço
para alocar
exemplos: Java, LISP, Prolog, Perl, Python, Modula-3, ...
contra-exemplos: C, Pascal, C++, ...
I
marcação
coleta ou compactação
caso haja compactação: cálculo de destino; atualização dos
apontadores; cópia dos blocos
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
288
Marcação e coleta
Marcação e coleta (cont.)
Exemplo de situação inicial:
I
Hipóteses
I
I
I
I
I
I
I
I
Localização conhecida das variáveis apontadoras na pilha de execução.
Localização conhecida de apontadores em cada bloco.
Blocos de tamanho fixo ou com campos de comprimento.
Marcas de utilização em cada bloco, inicialmente falsas.
f
supõe blocos iguais
setas mais fortes: apontadores nas variáveis na pilha de execução
blocos acessı́veis a serem marcados marcados em cor cinza
f
f
f
f
f
f
f
f
f
f
f
t
f
t
f
t
t
f
t
t
f
f
f
f
f
f
f
f
f
Após a marcação:
Algoritmo:
I
I
Percurso análogo à pré-ordem e marcação a partir das variáveis na
pilha.
Percurso linear da memória para coleta de blocos livres e restauração
das marcas.
f
t
t
Após a coleta:
f
f
f
disp
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
289
Marcação e coleta (cont.)
I
I
I
Gerenciamento de memória
290
Marcação e coleta (cont.)
Hipóteses simplificadoras:
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Função de marcação:
tamanho fixo de registros
localização conhecida dos apontadores (um vetor)
v o i d Marcar ( ApBloco p ) {
int i ;
i f ( p!=NULL) {
i f ( ! p−>marca ) {
p−>marca = t r u e ;
f o r ( i =0; i <p−>numAps ; i ++)
Marcar ( p−>a p o n t s [ i ] ) ;
}
}
} / ∗ Marcar ∗/
Declarações:
t y p e d e f s t r u c t B l o c o ∗ ApBloco ;
typedef s t r u c t Bloco {
B o o l e a n marca ;
ApBloco d e s t i n o ; /∗ s e h o u v e r compactação ∗/
. . .
i n t numAps ;
ApBloco a p o n t s [ NUM MAX APONTS ] ;
} Bloco ;
ApBloco d i s p ; /∗ i n i c i a l m e n t e t o d o s o s b l o c o s ∗/
B l o c o memoria [ TAM MEM DIN ] ;
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
A função Marcar deve ser chamada para cada variável apontadora na pilha
de execução.
291
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
292
Marcação e coleta (cont.)
Marcação e compactação
Função de coleta:
I
Hipóteses
I
void Coletar () {
int i ;
d i s p = NULL ;
f o r ( i =0; i <TAM MEM DIN ; i ++)
i f ( memoria [ i ] . marca ) /∗ em u s o ∗/
memoria [ i ] . marca = f a l s e ;
e l s e { /∗ i n s e r e na l i s t a d i s p o nı́ v e l ∗/
memoria [ i ] . a p o n t s [ 0 ] = d i s p ;
d i s p = &(memoria [ i ] ) ;
}
} /∗ C o l e t a r ∗/
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
I
I
I
I
Algoritmo:
I
I
I
I
Gerenciamento de memória
Localização conhecida das variáveis apontadoras na pilha de execução.
Localização conhecida de apontadores em cada bloco.
Blocos de tamanho fixo ou com campos de comprimento.
Marcas de utilização em cada bloco, inicialmente falsas.
Percurso análogo à pré-ordem e marcação a partir das variáveis na
pilha.
Cálculo dos novos endereços dos blocos.
Atualização dos campos apontadores.
Compactação (cópia).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
293
Marcação e compactação (cont.)
Marcação e compactação (cont.)
Exemplo de situação inicial:
Após o cálculo dos novos endereços (tracejados):
supõe blocos iguais
setas mais fortes: apontadores nas variáveis na pilha de execução
I blocos acessı́veis a serem marcados marcados em cor cinza
Gerenciamento de memória
294
I
I
f
t
t
t
f
t
f
t
t
f
t
t
Após a atualização dos apontadores, inclusive os da pilha:
f
f
f
f
f
f
f
f
f
f
f
f
f
Após a marcação:
f
t
t
t
f
t
f
t
t
f
t
t
t
t
f
t
f
t
t
f
t
t
f
f
f
Após a compactação:
t
disp
Após o cálculo dos novos endereços (tracejados):
f
f
t
t
t
f
t
f
t
t
f
t
f
f
f
f
f
f
f
f
t
A variável disp aponta para o inı́cio da área contı́gua liberada pela
operação de compactação (não é necessário usar uma lista ligada).
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
295
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
296
Marcação e compactação (cont.)
Marcação e compactação (cont.)
I
São adotadas as mesmas hipóteses do caso de marcação e coleta.
I
A função marcar é a mesma.
I
Função de cálculo dos novos endereços:
Função de atualização dos apontadores:
void A t u a l i z a () {
int i , j = 0;
f o r ( i =0; i <TAM MEM DIN ; i ++)
i f ( memoria [ i ] . marca )
f o r ( j =0; j <memoria [ i ] . numAps ; j ++) {
memoria [ i ] . a p o n t s [ j ] =
( memoria [ i ] . a p o n t s [ j ])−> d e s t i n o ;
}
} /∗ A t u a l i z a ∗/
void C a l c u l a r D e s t i n o () {
int i , j = 0;
f o r ( i =0; i <TAM MEM DIN ; i ++)
i f ( memoria [ i ] . marca ) {
memoria [ i ] . d e s t i n o = &(memoria [ j ] ) ;
j ++;
}
d i s p = &(memoria [ j ] ) ; /∗ p r i m e i r o b l o c o l i v r e ∗/
} /∗ C a l c u l a r D e s t i n o ∗/
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
Devem ser atualizadas também todas as variáveis apontadoras na pilha de
execução.
297
Marcação e compactação (cont.)
Gerenciamento de memória
298
Contagem de referências
Função de compactação:
v o i d Move ( ) {
int i ;
f o r ( i =0; i <TAM MEM DIN ; i ++)
i f ( memoria [ i ] . marca ) {
memoria [ i ] . marca = f a l s e ;
∗ ( memoria [ i ] . d e s t i n o ) = memoria [ i ] ;
}
} /∗ Move ∗/
Adaptação para blocos de tamanho variável: introduzir o campo tamanho
em cada bloco e adaptar as funções.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
299
I
As técnicas de coleta de lixo (marcação e coleta ou compactação)
encontram e liberam toda a memória disponı́vel de uma vez.
I
O processo pode ser bastante demorado, com tempo de execução
proporcional ao tamanho total da memória dinâmica.
I
A execução da coleta de lixo interrompe o processo em curso; esta
interrupção pode demorar mais do que seria aceitável am algumas
aplicações.
I
Dependendo da complexidade das estruturas de dados criadas pelo
programa, a fase de marcação pode exigir memória adicional
apreciável para manter a pilha de execução.
I
A técnica de contagem de referências tem a caracterı́stica de, em
geral, distribuir o tempo de gerenciamento de memória ao longo da
execução normal do programa.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
300
Contagem de referências (cont.)
I
Contagem de referências (cont.)
Cada bloco alocado possui um campo inteiro refs contendo o número de
variáveis (normais ou dinâmicas) que apontam para o bloco.
I
Durante a alocação de um bloco, o seu campo refs recebe o valor inicial 1.
I
Toda variável ou campo apontador, antes de ser atribuı́do, recebe o valor
NULL.
I
I
I
I
I
I
I
v o i d A t r i b u i A p o n t ( ApBloco ∗p ,
ApBloco q ) {
i f ( q!=NULL) ( q−>r e f s )++;
i f ( ( ∗ p )!=NULL) {
( ( ∗ p)−> r e f s )−−;
i f ( ( ( ∗ p)−> r e f s )==0)
DesalocaRefs (∗ p ) ;
}
∗p = q ;
}
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
301
desaloca o bloco apontado por p
decrementa os contadores dos blocos referidos em p
caso algum destes contadores torne-se nulo, a função é chamada
recursivamente
Problemas:
I
Todo comando de atribuição que envolve apontadores é implementado pela
função AtrbuiApont(ApBloco *p, ApBloco q):
t y p e d e f s t r u c t B l o c o ∗ ApBloco ;
typedef s t r u c t Bloco {
int refs ;
. . .
i n t numAps ;
ApBloco
a p o n t s [ NUM MAX APONTS ] ;
} Bloco ;
A função DesalocaRefs(p):
dependendo das estruturas de dados, o tempo de execução de comando
de atribuição entre apontadores é imprevisı́vel devido à recurisividade
da função DesalocaRefs
o método, como exposto, não funciona para estruturas com
circularidades; exemplo:
2
1
1
1
1
1
1
1
p
após a atribuição p = NULL:
1
1
p
Os nós da lista não seriam liberados. Alguns sistemas utilizam um
esquema misto: contagem de referências e coleta de lixo.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Gerenciamento de memória
302
Tipos abstratos de dados
I
I
I
Abstração de Dados e Objetos
typedef void ∗ Figura ;
Figura Retangulo ( f l o a t alt , f l o a t l a r g ) ;
Figura Circulo ( float raio ) ;
F i g u r a Quadrado ( f l o a t l a d o ) ;
f l o a t Area ( F i g u r a f i g ) ;
v o i d T r a n s l a d a r ( F i g u r a f i g , f l o a t dx , f l o a t dy ) ;
void Desenhar ( Figura f i g ) ;
I
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
Um tipo abstrato de dados (TAD) é constituı́do por um conjunto de
valores e um conjunto de operações sobre estes valores.
Os valores possuem uma representação e podem ser muito simples
(inteiros, bytes, ...) ou bastante complexos (pilhas, árvores, ...).
Exemplo de especificação de um TAD Figura através de declarações
em C:
303
A espoecificação de um tipo como “void ∗” é uma técnica comum
em C para “esconder” a implementação.
Normalmente, estas declarações, chamadas às vezes de interface ou
API (Application Programming Interface) estariam num arquivo
denominado figuras.h.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
304
Tipos abstratos de dados (cont.)
I
I
Tipos abstratos de dados (cont.)
Usando a especificação, é possı́vel escrever programas que utilizam o
TAD, mesmo sem completar a sua implementação.
Exemplo de utilização do TAD Figura:
I
I
t y p e d e f enum { RETANGULO, CIRCULO , QUADRADO } F o r m a F i g u r a ;
#i n c l u d e ” f i g u r a s . h”
i n t main ( ) {
Figura c = Circulo (10.0);
Figura r = Retangulo (10.0 , 2 0 . 0 ) ;
F i g u r a q = Quadrado ( 5 0 . 0 ) ;
Transladar ( r , 5 . 0 , 8 . 0 ) ;
Desenhar ( q ) ;
p r i n t f ( ”%f \n” , Area ( c ) ) ;
p r i n t f ( ”%f \n” , Area ( r ) ) ;
p r i n t f ( ”%f \n” , Area ( q ) ) ;
return 0;
} /∗ main ∗/
I
I
typedef struct {
F o r m a F i g u r a f orma ;
f l o a t posx , p o s y ;
union {
struct {
float alt , larg ;
} lados ;
float raio ;
} dados ;
} RegFigura , ∗ Figura ;
As funções Circulo, Retangulo e Quadrado devem construir e devolver
as representações dos valores correspondentes (construtores).
A função main poderia estar num arquivo denominado main.c.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
305
Tipos abstratos de dados (cont.)
I
I
Figura
?
?
forma posx
posy
lados
Retangulo
0
forma posx
Circulo
posy
alt
posy
raio
larg
1
?
forma posx
lados
Quadrado
2
forma posx
posy
alt
larg
Deve-se notar a diferença entre os tipos Figura e Figura.
Normalmente, estas declarações (e as seguintes) estariam num
arquivo figuras.c.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
306
Tipos abstratos de dados (cont.)
Declarações dos construtores:
Figura Retangulo ( f l o a t alt ,
float larg ) {
Figura f =
malloc ( sizeof ( RegFigura ) ) ;
f −>forma = RETANGULO ;
f −>p o s x = 0 . 0 ;
f −>p o s y = 0 . 0 ;
f −>d a d o s . l a d o s . a l t = a l t ;
f −>d a d o s . l a d o s . l a r g = l a r g ;
return f ;
} /∗ R e t a n g u l o ∗/
A implementação de um TAD depende de vários fatores, mas deve
seguir sempre a sua especificação.
Exemplo de declarações “naturais” para implementar o TAD Figura:
Declarações das funções:
Figura Circulo ( float raio ) {
Figura f =
malloc ( sizeof ( RegFigura ) ) ;
f −>forma = CIRCULO ;
f −>p o s x = 0 . 0 ;
f −>p o s y = 0 . 0 ;
f −>d a d o s . r a i o = r a i o ;
return f ;
} /∗ C i r c u l o ∗/
F i g u r a Quadrado ( f l o a t l a d o ) {
Figura f =
Retangulo ( lado , lado ) ;
f −>forma = QUADRADO;
return f ;
} /∗ Quadrado ∗/
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
307
f l o a t Area ( F i g u r a f i g ) {
Figura f = fig ;
s w i t c h ( f −>forma ) {
c a s e RETANGULO :
c a s e QUADRADO:
r e t u r n ( f −>d a d o s . l a d o s . a l t ) ∗
( f −>d a d o s . l a d o s . l a r g ) ;
c a s e CIRCULO :
r e t u r n PI ∗ ( f −>d a d o s . r a i o ) ∗
( f −>d a d o s . r a i o ) ;
default :
e x i t ( 1 ) ; /∗ I m p o s sı́ v e l ∗/
}
} /∗ Area ∗/
void Transladar ( Figura f ig ,
f l o a t dx ,
f l o a t dy ) {
Figura f = fig ;
f −>p o s x += dx ;
f −>p o s y += dy ;
} /∗ T r a n s l a d a r ∗/
void Desenhar ( Figura f ) {
/∗ Não f o i i m p l e m e n t a d a ∗/
} /∗ D e s e n h a r ∗/
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
308
Tipos abstratos de dados (cont.)
I
I
I
I
Tipos abstratos de dados (cont.)
Nesta implementação do TAD Figura, a estrutura de dados que
implementa o tipo e as funções são implementadas separadamente.
É possı́vel mudar a implementação de maneira que as funções passem
fazer parte da própria estrutura de dados – uma caracterı́stica de
objetos; neste caso são denominados métodos.
Nesta nova implementação do exemplo, por simplicidade, a técnica
será aplicada somente à função Area, mas poderia ser estendida às
outras funções.
Trata-se de uma nova implementação da mesma interface;
consequentemente os arquivos figuras.h (repetido abaixo) e
main.c permanecem iguais.
typedef void ∗ Figura ;
Figura Retangulo ( f l o a t alt , f l o a t l a r g ) ;
Figura Circulo ( float raio ) ;
F i g u r a Quadrado ( f l o a t l a d o ) ;
f l o a t Area ( F i g u r a f i g ) ;
v o i d T r a n s l a d a r ( F i g u r a f i g , f l o a t dx , f l o a t dy ) ;
void Desenhar ( Figura f i g ) ;
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
309
Tipos abstratos de dados (cont.)
Declaração de Figura com um método:
t y p e d e f f l o a t f u n c A r e a ( F i g u r a ) ; /∗ t i p o f u n ç ã o ∗/
t y p e d e f enum { RETANGULO, CIRCULO , QUADRADO } F o r m a F i g u r a ;
typedef struct {
F o r m a F i g u r a forma ;
f l o a t posx , p o s y ;
f u n c A r e a ∗ Area ;
/∗ a p o n t a d o r p a r a f u n ç ã o ∗/
union {
struct { float alt , larg ; } lados ;
float raio ;
} dados ;
} RegFigura , ∗ Figura ;
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
310
Tipos abstratos de dados (cont.)
Declarações dos construtores:
Funções do tipo funcArea:
Figura Retangulo ( f l o a t alt ,
float larg ) {
Figura f =
malloc ( sizeof ( RegFigura ) ) ;
f −>forma = RETANGULO ;
f −>p o s x = 0 . 0 ;
f −>p o s y = 0 . 0 ;
f −>Area = A r e a R e t a n g u l o ;
f −>d a d o s . l a d o s . a l t = a l t ;
f −>d a d o s . l a d o s . l a r g = l a r g ;
return f ;
} /∗ R e t a n g u l o ∗/
f l o a t AreaRetangulo ( Figura f i g ) {
Figura f = fig ;
r e t u r n ( f −>d a d o s . l a d o s . a l t ) ∗ ( f −>d a d o s . l a d o s . l a r g ) ;
} /∗ A r e a R e t a n g u l o ∗/
float AreaCirculo ( Figura f i g ) {
Figura f = fig ;
r e t u r n PI ∗ ( f −>d a d o s . r a i o ) ∗ ( f −>d a d o s . r a i o ) ;
} /∗ A r e a C i r c u l o ∗/
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
311
Figura Circulo ( float raio ) {
Figura f =
malloc ( sizeof ( RegFigura ) ) ;
f −>forma = CIRCULO ;
f −>p o s x = 0 . 0 ;
f −>p o s y = 0 . 0 ;
f −>Area = A r e a C i r c u l o ;
f −>d a d o s . r a i o = r a i o ;
return f ;
} /∗ C i r c u l o ∗/
F i g u r a Quadrado ( f l o a t l a d o ) {
Figura f =
Retangulo ( lado , lado ) ;
f −>forma = QUADRADO;
return f ;
} /∗ Quadrado ∗/
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
312
Tipos abstratos de dados (cont.)
Objetos
I
Declarações das funções:
I
f l o a t Area ( F i g u r a f i g ) {
r e t u r n ( ( F i g u r a ) f i g )−>Area ( f i g ) ;
}
I
v o i d T r a n s l a d a r ( F i g u r a f i g , f l o a t dx , f l o a t dy ) {
Figura f = fig ;
f −>p o s x += dx ;
f −>p o s y += dy ;
} /∗ T r a n s l a d a r ∗/
I
I
I
O exemplo anterior demonstra que é possı́vel simular, dentro de
algumas limitações, a implementação de objetos numa linguagem que
não incorpora este conceito.
Há vários aspectos que ficam a cargo do próprio programador,
especialmente a consistência de tipos, fonte comum de erros.
O exemplo anterior será transformado de maneira a ilustrar a
implementação de objetos numa linguagem que possui este conceito.
Será usada uma linguagem fictı́cia, uma extensão simples de C.
Não serão tratados vários aspectos como por exemplo polimorfismo,
visibilidade etc.
Figura
Exemplo de hierarquia das classes:
void Desenhar ( Figura f i g ) {
/∗ Não f o i i m p l e m e n t a d a ∗/
} /∗ D e s e n h a r ∗/
Cı́rculo
Retângulo
Quadrado
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
313
Objetos (cont.)
c l a s s Figura {
f l o a t posx , p o s y ;
/∗ não e x i s t e c o n s t r u t o r ∗/
f l o a t Area ( ) { } ;
void Desenhar ( ) { } ;
f l o a t T r a n s l a d a r ( f l o a t dx , dy ) {
t h i s . p o s x += dx ;
t h i s . p o s y += dy ;
}
} /∗ F i g u r a ∗/
Abstração de Dados e Objetos
314
Objetos (cont.)
posx
0
posy
(Classe pai)
1
Area (Figura)
2
Desenhar (Figura)
3
Transladar (Figura)
Todos os objetos de uma classe apontam para a mesma tabela de
métodos. Pode haver mais informações. Neste exemplo, todas as funções
foram transformadas em métodos.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
315
c l a s s Retangulo extends Figura {
float alt , larg ;
Retangulo ( f l o at a , f l o at l ) {
this . alt = a;
this . larg = l ;
posx
posy
alt
t h i s . posx = 0 . 0 ;
t h i s . posy = 0 . 0 ;
Classe Figura
0
}
Area (Retangulo)
1
f l o a t Area ( ) {
Desenhar (Retangulo)
2
return a l t ∗ l a r g ;
Transladar (Figura)
3
}
Girar90 (Retangulo)
4
void Desenhar ( ) { . . . } ;
Retangulo Girar90 () {
r e t u r n new R e t a n g u l o ( t h i s . l a r g , t h i s . a l t ) ;
}
} /∗ R e t a n g u l o ∗/
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
larg
316
Objetos (cont.)
Objetos (cont.)
c l a s s Quadrado e x t e n d s R e t a n g u l o {
Quadrado ( f l o a t l ) {
super ( l , l ) ;
}
posx
posy
} /∗ R e t a n g u l o ∗/
alt
0
Classe Retângulo
1
Area (Retangulo)
2
Desenhar (Retangulo)
3
Transladar (Figura)
4
Girar90 (Retangulo)
c l a s s Circulo extends Figura {
float raio ;
Circulo ( float r ) {
t h i s . posx = 0 . 0 ;
t h i s . posy = 0 . 0 ;
this . raio = r ;
0
}
1
f l o a t Area ( ) {
r e t u r n PI ∗ s q r ( r a i o ) ;
2
}
3
void Desenhar ( ) { . . . } ;
4
void D u p l i c a r ( ) {
t h i s . r a i o = 2.0∗ t h i s . r a i o ;
}
} /∗ R e t a n g u l o ∗/
larg
Somente o construtor é diferente da classe Retangulo.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
317
Objetos (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
posx
posy
raio
Classe Figura
Area (Circulo)
Desenhar (Circulo)
Transladar (Figura)
Duplicar (Circulo)
Abstração de Dados e Objetos
318
Objetos (cont.)
Representação de todas as classes:
Exemplo de uso dos objetos:
Figura
0
(Classe pai)
1
Area (Figura)
2
Desenhar (Figura)
3
Transladar (Figura)
Retangulo
0
Circulo
0
1
Area (Retangulo)
1
Area (Circulo)
2
Desenhar (Retangulo)
2
Desenhar (Circulo)
3
Transladar (Figura)
3
Transladar (Figura)
4
Girar90 (Retangulo)
4
Duplicar (Circulo)
Quadrado
0
1
Area (Retangulo)
2
Desenhar (Retangulo)
3
Transladar (Figura)
4
Girar90 (Retangulo)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
i n t main ( ) {
F i g u r a f = new C i r c u l o ( 1 0 . 0 ) ;
Retangulo r =
new R e t a n g u l o ( 1 0 . 0 , 2 0 . 0 ) ;
Quadrado q = new Quadrado ( 5 0 . 0 ) ;
C i r c u l o c = new C i r c u l o ( 3 0 . 0 ) ;
p r i n t f ( ”%f \n” , f . Area ( ) ) ;
p r i n t f ( ”%f \n” , r . Area ( ) ) ;
c . Desenhar ( ) ;
f = q;
f . Transladar (5.0 ,8.0);
f . Desenhar ( ) ;
p r i n t f ( ”%f \n” , f . Area ( ) ) ;
/∗ comandos i n v á l i d o s ∗/
f . Duplicar ();
f . Girar90 ( ) ;
c . Girar90 ( ) ;
c = r;
q = f;
} /∗ main ∗/
Os comandos inválidos seriam detectados pelo compilador.
Abstração de Dados e Objetos
319
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Abstração de Dados e Objetos
320
Generalidades
I
Ordenação interna e externa
I
Ordenação ótima por comparações: O(n log n)
Algoritmos por comparação:
I
Algoritmos de ordenação
I
I
I
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
321
transposição (bubblesort, quicksort)
inserção (inserção simples, shellsort)
seleção (seleção simples, heapsort)
intercalação (iterativo, recursivo)
I
Outros algoritmos: distribuição (radix sort)
I
Ordenação estável: mantém a ordem relativa dos registros de com
chaves iguais.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
Ordenação ótima por comparações
Ordenação ótima por comparações (cont.)
Árvore de decisão para ordenar três elementos x1 , x2 e x3 :
Caso geral de n elementos:
I
x1 ≤ x2
V
F
I
x2 ≤ x3
x2 ≤ x3
V
F
x1 , x2 , x3
V
x1 ≤ x3
V
x1 , x3 , x2
x3 , x1 , x2
V
x2 , x1 , x3
x3 , x2 , x1
F
x2 , x3 , x1
I
A árvore tem 3! = 6 folhas (permutações de 3 elementos).
I
A altura da árvore é 3.
I
Portanto, o número mı́nimo de comparações, no pior caso, é 3.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
A árvore de decisão deverá ter n! folhas (número de permutações de
n elementos).
Uma árvore de altura h tem no máximo 2h folhas.
Deve-se ter, portanto:
2h ≥ n!
=⇒ h ≥ dlog2 (n!)e
Pela aproximação de Stirling:
log2 n
+ O(1)
dlog2 (n!)e = n log2 n − n/(ln 2) +
2
Para valores grandes de n, o primeiro termo é dominante:
F
x1 ≤ x3
F
I
322
dlog2 (n!)e ≈ n log2 n
I
I
323
O número mı́nimo de comparações, no pior caso, é O(n log2 n).
Portanto, não existe nenhum algoritmo de ordenação mais eficiente
que utiliza apenas comparações de elementos.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
324
Algoritmos: declarações comuns
Algoritmo bubble sort
0
n-1
d
typedef struct Vetor {
int n ;
i n t dados [ 1 ] ;
} V e t o r , ∗ ApVetor ;
v o i d t r o c a ( i n t ∗x , i n t ∗ y ) {
int t = ∗x ;
∗x = ∗y ;
∗y = t ;
} /∗ t r o c a ∗/
j =⇒
v o i d b u b b l e S o r t ( ApVetor v ) {
/∗ Exemplo de t r a n s p o s i ç ã o ∗/
i n t n = v−>n , i , j ;
i n t ∗d = ( v−>d a d o s ) ;
f o r ( i=n −1; i >0; i −−)
f o r ( j =0; j <i ; j ++)
i f ( d [ j ]>d [ j +1])
t r o c a (&d [ j ] ,& d [ j + 1 ] ) ;
} /∗ b u b b l e S o r t ∗/
I
Os algoritmos de ordenação serão apresentados como funções em
linguagem C que ordenam um vetor de dados que faz parte de uma
estrutura denominada Vetor.
I
Nesta declaração, n denota o tamanho verdadeiro do vetor dados que
dependerá do parâmetro passado à função malloc quando o vetor for
alocado.
I
Vários algoritmos fazem trocas de valores entre elementos do vetor
indicadas por chamadas da função troca.
I
I
I
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
325
Inserção simples
0
n-1
I
I
326
p
0
n-1
d
i =⇒
v o i d i n s e r c a o ( ApVetor v ) {
i n t n = v−>n , i , j , t ;
i n t ∗d = ( v−>d a d o s ) ;
f o r ( i =0; i <n −1; i ++) {
t = d [ i +1];
j = i;
w h i l e ( ( j >=0)&&(t<d [ j ] ) ) {
d [ j +1] = d [ j ] ;
j −−;
}
d [ j +1] = t ;
}
} /∗ i n s e r c a o ∗/
I
Algoritmos de ordenação
Seleção simples
t
i =⇒
I
Os elementos entre i+ 1 e n−1 já estão ordenados.
Os elementos d[j] (abaixo de i) são “empurrados” se necessáro; o
maior deles acaba em seu lugar final.
Verifica-se facilmente que o número de comparações executado por
este algoritmo é sempre (n2 −n)/2 (da ordem de O(n2 )).
É um algoritmo estável.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
d
I
⇐= i
Os elementos entre 0 e i já estão ordenados.
Os elementos menores do que d[i+1] são “empurrados” à direita e
d[i+1] inserido no seu lugar.
No pior caso, O(n2 ) comparações; no melhor caso, O(n).
Um bom algoritmo se os dados já estão parcialmente ordenados.
É um algoritmo estável.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
327
v o i d s e l e c a o ( ApVetor v ) {
i n t n = v−>n , i , j , p ;
i n t ∗d = ( v−>d a d o s ) ;
f o r ( i =0; i <n −1; i ++) {
p = i;
f o r ( j=i +1; j <n ; j ++)
i f ( d [ j ]<d [ p ] )
p = j;
t r o c a (&d [ i ] ,& d [ p ] ) ;
}
} /∗ s e l e c a o ∗/
I
I
I
I
Os elementos entre 0 e i−1 já estão ordenados.
O elemento mı́nimo entre as posições i e n−1 (d[p]) troca de lugar
com o elemento d[i].
O número de comparações é sempre da ordem de O(n2 ).
É um algoritmo estável.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
328
Algoritmo Quicksort
Algoritmo Quicksort (cont.)
I
Quicksort foi idealizado por C. A. R. Hoare em 1962.
I
É um algoritmo recursivo que ordena segmentos do vetor dado.
I
A ordenação do vetor inteiro é realizada através da chamada de uma
função auxiliar com argumentos que cobrem o vetor:
v o i d q u i c k S o r t A u x ( ApVetor v , i n t esq , i n t d i r ) {
/∗ s u p õ e esq<=d i r ∗/
i n t ∗d = ( v−>d a d o s ) ;
i n t i = esq , j = d i r ;
i n t p i v o t = d [ ( i n t ) ( ( e s q+d i r ) / 2 ) ] ;
/∗ p a r t i c i o n a ∗/
do {
w h i l e ( d [ i ]< p i v o t ) i ++;
w h i l e ( d [ j ]> p i v o t ) j −−;
i f ( i <=j ) {
t r o c a (&d [ i ] ,& d [ j ] ) ;
i ++; j −−;
}
} w h i l e ( i <=j ) ;
/∗ o r d e n a ∗/
i f ( esq<j ) q u i c k S o r t A u x ( v , esq , j ) ;
i f ( d i r >i ) q u i c k S o r t A u x ( v , i , d i r ) ;
} /∗ q u i c k S o r t A u x ∗/
v o i d q u i c k S o r t ( ApVetor v ) {
q u i c k S o r t A u x ( v , 0 , ( v−>n ) −1);
} /∗ q u i c k S o r t ∗/
I
A função auxiliar quickSortAux implementa de fato o algoritmo.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
329
Algoritmo Quicksort (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmo Quicksort (cont.)
do {
w h i l e ( d [ i ]< p i v o t ) i ++;
w h i l e ( d [ j ]> p i v o t ) j −−;
i f ( i<=j ) {
t r o c a (&d [ i ] , & d [ j ] ) ;
i ++; j −−;
}
} w h i l e ( i<=j ) ;
i f ( esq<j ) q u i c k S o r t A u x ( v , esq , j ) ;
i f ( d i r >i ) q u i c k S o r t A u x ( v , i , d i r ) ;
I
I
Inı́cio do particionamento:
p
Algoritmos de ordenação
330
do {
w h i l e ( d [ i ]< p i v o t ) i ++;
w h i l e ( d [ j ]> p i v o t ) j −−;
i f ( i<=j ) {
t r o c a (&d [ i ] ,& d [ j ] ) ;
i ++; j −−;
}
} w h i l e ( i<=j ) ;
i f ( esq<j ) q u i c k S o r t A u x ( v , esq , j ) ;
i f ( d i r >i ) q u i c k S o r t A u x ( v , i , d i r ) ;
Situação após uma troca:
0
esq
i
j
≥p
≤p
dir
n-1
dir
n-1
(pivot)
d
0
esq
dir
n-1
≤p
d
I
⇐= j
i =⇒
Situação quando termina o particionamento:
0
I
Situação genérica após uma troca:
0
esq
≥p
esq
j
i
d
i
j
≥p
≤p
dir
n-1
≤p
≥p
d
≤p
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Pode haver apenas um ou nenhum elemento entre j e i. Se houver,
ele é necessariamente igual ao pivô e está na sua posição final.
≥p
Algoritmos de ordenação
331
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
332
Algoritmo Quicksort (cont.)
Algoritmo Quicksort (cont.)
do {
w h i l e ( d [ i ]< p i v o t ) i ++;
w h i l e ( d [ j ]> p i v o t ) j −−;
i f ( i<=j ) {
t r o c a (&d [ i ] , & d [ j ] ) ;
i ++; j −−;
}
} w h i l e ( i<=j ) ;
i f ( esq<j ) q u i c k S o r t A u x ( v , esq , j ) ;
i f ( d i r >i ) q u i c k S o r t A u x ( v , i , d i r ) ;
I
I
I
I
I
I
Situação quando termina o particionamento:
esq
0
j
i
Escolha do pivô:
I
Eficiência:
n-1
dir
I
d
I
≤p
I
≥p
I
I
Situação após as chamadas recursivas – o segmento está ordenado:
esq
0
n-1
dir
I
d
em princı́pio, o algoritmo funciona com qualquer valor do pivô
o ideal seria um pivô que particiona o segmento em duas partes de
comprimentos iguais
algumas implementações utilizam a média de alguns poucos elementos
na implementação aqui exibida foi usado o valor do elemento do meio
no pior caso o algoritmo realiza da ordem de O(n2 ) operações
em média e no melhor caso são O(n log n) operações
na prática são quase sempre O(n log n) operações
é o algoritmo de ordenação interna mais utilizado e faz parte das
bibliotecas de várias linguagens (por exemplo, qsort em C)
Estabilidade:
I
I
sob a forma apresentada, o algoritmo não é estável
exercı́cios:
I
I
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
333
Algoritmo Quicksort (cont.)
exibir um exemplo que demonstra a falta de estabilidade
modificar o algoritmo para que seja estável
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Exemplo de execução do Quicksort:
Pivot: 65
03
07
09
<
58
30
12
78
23
73
40
*
65
92
42
87
49
27
29
12
44
i
44
03
07
09
58
30
40
73
40
65
92
42
87
49
27
30
12
44
40
23
i
23
29
65
92
42
87
49
58
30
12
44
40
23
29
40
i
40
27
42
87
58
30
12
44
40
23
29
40
27
92
i
49
09
58
30
12
44
40
23
29
40
27
49
42
i
42
j
87
j
87
i
49
j
92
27
j
65
29
j
73
03
07
09
58
03
07
09
03
07
09
03
07
30
i
12
j
12
44
*
58
29
40
27
49
>
42
30
i
44
40
j
40
58
29
40
27
49
42
30
44
40
58
29
40
27
49
42
Vetor original:
07
49
73
58
30
72
44
78
23
09
40
65
92
42
87
03
27
29
40
12
------------------------------------------------------------------------------------------------------
07
03
07
03
Pivot: 03
<
*
03
07
j
i
Pivot: 07
<*
03
07
j
73
i
09
09
j
>
09
58
30
72
44
78
23
58
i
58
i
30
72
44
78
30
72
44
78
23
j
23
334
Algoritmo Quicksort (cont.)
(< e > delimitam o segmento corrente; ∗ marca o pivô)
Pivot: 09
<
07
03
Algoritmos de ordenação
*
09
49
27
29
40
42
87
j
87
>
12
40
65
92
42
73
40
65
92
49
27
29
40
12
73
40
65
92
42
87
49
27
29
40
12
40
j
78
>
72
72
78
72
73
78
72
65
73
78
72
92
65
73
78
72
87
92
65
73
78
72
87
92
65
73
78
72
87
92
65
73
78
72
Pivot: 23
58
30
72
44
78
23
73
40
65
92
42
87
49
27
29
40
12
58
30
72
44
78
23
73
40
65
92
42
87
49
27
29
40
12
03
07
09
<
23
03
07
09
23
09
<*
12
j
Pivot: 23
>
09
i
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
03
335
07
>
23
i
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
336
Algoritmo Quicksort (cont.)
Algoritmo Quicksort (cont.)
Pivot: 29
03
07
09
12
23
<
27
03
07
09
12
23
27
03
07
09
12
23
27
44
i
29
29
j
40
40
i
40
i
58
58
j
58
*
29
49
>
42
Pivot: 40
30
44
40
j
40
87
92
65
73
78
72
30
49
42
87
92
65
73
78
72
44
40
30
49
42
87
92
65
73
78
72
03
07
09
12
23
27
29
30
40
03
07
09
12
23
27
29
30
40
<
40
i=j
40
j
*
44
49
>
42
87
92
65
73
78
72
58
i
44
49
42
87
92
65
73
78
72
<
42
*
44
i
44
>
58
87
92
65
73
78
72
58
87
92
65
73
78
72
<*
49
>
58
i
87
92
65
73
78
72
92
*
87
73
78
>
72
87
73
78
72
58
Pivot: 44
Pivot: 27
03
07
09
12
23
j
<*
27
>
29
i
40
58
44
40
30
49
42
87
92
65
73
78
03
07
09
12
23
27
29
30
40
40
03
07
09
12
23
27
29
30
40
40
42
j
09
12
23
27
29
30
40
40
42
44
j
72
49
j
49
i
Pivot: 40
03
07
09
12
23
27
29
<
30
03
07
09
12
23
27
29
30
03
07
09
12
23
27
29
30
58
i
40
i=j
40
j
44
44
44
i
*
40
j
58
58
40
49
>
42
Pivot: 49
87
92
65
73
78
72
03
40
49
42
87
92
65
73
78
72
40
49
42
87
92
65
73
78
72
07
Pivot: 65
03
07
09
12
23
27
29
30
40
40
42
44
49
58
03
07
09
12
23
27
29
30
40
40
42
44
49
58
Pivot: 30
03
07
09
12
23
27
29
j
<*
30
>
40
i
44
58
40
49
42
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
87
92
65
73
78
72
Algoritmos de ordenação
337
Algoritmo Quicksort (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
<
65
i=j
65
j
92
i
Algoritmos de ordenação
338
Intercalação iterativa (Mergesort)
Pivot: 73
03
07
09
12
23
27
29
30
40
40
42
44
49
58
65
<
72
03
07
09
12
23
27
29
30
40
40
42
44
49
58
65
72
09
12
23
27
29
30
40
40
42
44
49
58
65
j
09
12
23
27
29
30
40
40
42
44
49
58
65
87
i
73
j
*
73
87
i
78
j
78
>
92
07
O algoritmo de intercalação iterativa foi provavelmente um dos
primeiros algoritmos de ordenação interna propostos: John von
Neumann (1945).
I
O algoritmo consiste em várias passagens pelo vetor, intercalando
segmentos consecutivos de tamanhos 1, 2, 4, 8, ..., até completar o
vetor.
I
Utiliza um vetor auxiliar; os dois vetores são usados alternadamente
para guardar os resultados da intercalação.
I
Se necessário, há um passo adicional para copiar os resultados do
vetor auxiliar para o original.
I
O número de comparações deste algoritmo é da ordem de O(n log n)
(ótimo).
I
O algoritmo é estável.
92
Pivot: 72
03
I
<*
72
>
73
i
87
78
92
72
73
<
78
j
*
87
i
>
92
<*
87
>
92
i
Pivot: 78
03
07
Pivot: 87
03
07
09
12
23
27
29
30
40
40
42
44
49
58
65
72
73
78
j
-----------------------------------------------------------------------------------------------------Resultado:
03
07
09
12
23
27
29
30
40
40
42
44
49
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
58
65
72
73
78
87
Algoritmos de ordenação
92
339
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
340
Intercalação iterativa (cont.)
Intercalação iterativa (cont.)
0
n-1
v→d
...
w→d
...
v→d
...
w→d
...
v→d
...
v o i d i n t e r c a l a I t e r a t i v o ( ApVetor v ) {
/∗ Ordena de 2 em 2 , de 4 em 4 , . . . , p o r i n t e r c a l a ç ã o ∗/
i n t n = v−>n ;
i n t td = 1 ;
/∗ 1 , 2 , 4 , . . . ∗/
i n t esq , d i r , l d ;
i n t tamanho = s i z e o f ( V e t o r )+ s i z e o f ( i n t ) ∗ ( n −1);
Boolean par = f a l s e ;
ApVetor w = ( ApVetor ) m a l l o c ( tamanho ) ;
w−>n = v−>n ;
•••
(continua)
Quando n não é uma potência de 2, os últimos segmentos de cada estágio
podem ficar mais curtos do que os outros.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
341
Intercalação iterativa (cont.)
Algoritmos de ordenação
342
Intercalação iterativa (cont.)
w h i l e ( td<n ) {
esq = 0; par = ! par ;
do {
d i r = e s q+t d ; l d = d i r+t d ;
i f ( d i r >=n ) { /∗ l a d o d i r e i t o v a z i o ∗/
d i r = n ; l d = n −1;
} e l s e i f ( l d >n )
ld = n ;
i f ( p a r ) i n t e r c a l a I t e r a t i v o A u x ( v , w , esq , d i r , l d ) ;
else
i n t e r c a l a I t e r a t i v o A u x (w , v , esq , d i r , l d ) ;
e s q = d i r+t d ;
} w h i l e ( esq<n ) ;
t d = 2∗ t d ;
}
i f ( p a r ) memcpy ( v , w , tamanho ) ;
f r e e (w ) ;
} /∗ i n t e r c a l a I t e r a t i v o ∗/
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
v o i d i n t e r c a l a I t e r a t i v o A u x ( ApVetor v , ApVetor w ,
i n t esq , i n t d i r , i n t l d ) {
/∗ I n t e r c a l a v . d a d o s [ e s q : d i r −1] e
v . d a d o s [ d i r : l d −1] em w . d a d o s [ e s q : l d −1] ∗/
i n t ∗ dv = ( v−>d a d o s ) , ∗dw = (w−>d a d o s ) ;
i n t i = esq , j = d i r , k= e s q ;
w h i l e ( ( i <d i r )&&( j <l d ) ) {
i f ( dv [ i ]<=dv [ j ] ) {
dw [ k ] = dv [ i ] ; i ++;
} else {
dw [ k ] = dv [ j ] ; j ++;
}
k++;
}
w h i l e ( i <d i r ) { dw [ k ] = dv [ i ] ; i ++; k++; }
w h i l e ( j <l d ) { dw [ k ] = dv [ j ] ; j ++; k++; }
} /∗ i n t e r c a l a I t e r a t i v o A u x ∗/
343
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
344
Intercalação iterativa (cont.)
Intercalação recursiva
Exemplo de execução:
Vetor original:
07
49
73
58
30
72
44
78
23
09
40
65
92
42
87
03
27
29
40
12
----------------------------------------------------------------------------------------------------
I
Passos do algoritmo:
I
td=1:
| 07
49 | 58
73 | 30
72 | 44
78 | 09
23 | 40
65 | 42
92 | 03
87 | 27
29 | 12
40 |
td=2:
| 07
49
73 | 30
44
78 | 09
23
65 | 03
42
92 | 12
27
40 |
I
58
72
40
87
29
I
I
td=4:
| 07
30
44
49
58
72
73
78 | 03
09
23
40
42
65
87
92 | 12
27
29
40 |
td=8:
| 03
07
09
23
30
40
42
44
58
65
72
73
78
87
92 | 12
27
29
40 |
td=16:
| 03
07
09
12
23
27
29
30
49
40
40
42
44
49
58
65
72
73
78
87
quebrar o vetor v dado em dois vetores v1 e v2 , de tamanhos
aproximadamente iguais
se o tamanho de v1 é maior que 1, ordená-lo recursivamente
se o tamanho de v2 é maior que 1, ordená-lo recursivamente
intercalar os vetores v1 e v2 , deixando o resultado no vetor v original
I
É fácil verificar que o número de comparações é da ordem de
O(n log n) (ótimo).
I
Se implementado corretamente, o algoritmo é estável.
92 |
---------------------------------------------------------------------------------------------------Resultado:
03
07
09
12
23
27
29
30
40
40
42
44
49
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
58
65
72
73
78
87
92
Algoritmos de ordenação
345
Intercalação recursiva (cont.)
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
346
Intercalação recursiva (cont.)
0
n-1
v→d
quebra
v1→d
v2→d
rec
rec
v1→d
v2→d
v o i d i n t e r c a l a R e c u r s i v o ( ApVetor v ) {
i n t n = v−>n ;
i f ( n>1) {
i n t ∗ dv = v−>d a d o s ; ApVetor v1 , v2 ;
i n t i , nv1 = ( i n t ) ( n / 2 ) , nv2 = n−nv1 ;
v1 = ( ApVetor ) m a l l o c ( s i z e o f ( V e t o r )+ s i z e o f ( i n t ) ∗ ( nv1 − 1 ) ) ;
v2 = ( ApVetor ) m a l l o c ( s i z e o f ( V e t o r )+ s i z e o f ( i n t ) ∗ ( nv2 − 1 ) ) ;
v1−>n = nv1 ; v2−>n = nv2 ;
f o r ( i =0; i <nv1 ; i ++) ( v1−>d a d o s ) [ i ] = dv [ i ] ;
f o r ( i =0; i <nv2 ; i ++) ( v2−>d a d o s ) [ i ] = dv [ i+nv1 ] ;
i n t e r c a l a R e c u r s i v o ( v1 ) ; i n t e r c a l a R e c u r s i v o ( v2 ) ;
i n t e r c a l a R e c u r s i v o A u x ( v1 , v2 , v ) ;
f r e e ( v1 ) ;
f r e e ( v2 ) ;
}
} /∗ i n t e r c a l a R e c u r s i v o ∗/
v→d
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
347
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
348
Intercalação recursiva (cont.)
Comparação dos algoritmos de ordenação interna
Tempos em milisegundos:
i n t e r c a l a R e c u r s i v o A u x ( ApVetor u , ApVetor v , ApVetor w) {
I n t e r c a l a o s v e t o r e s u e v , d e i x a n d o o r e s u l t a d o em w . ∗/
i = 0, j = 0, k;
nu = u−>n , nv = v−>n , n = nu+nv ;
∗ du = ( u−>d a d o s ) , ∗ dv = ( v−>d a d o s ) ,
∗dw = (w−>d a d o s ) ;
f o r ( k =0; k<n ; k++) {
i f ( ( i <nu)&&( j <nv ) ) {
i f ( du [ i ]<=dv [ j ] ) { dw [ k ] = du [ i ] ; i ++; }
e l s e { dw [ k ] = dv [ j ] ; j ++; }
} else {
i f ( i <nu ) { dw [ k ] = du [ i ] ; i ++; }
e l s e { dw [ k ] = dv [ j ] ; j ++; }
}
}
} /∗ i n t e r c a l a R e c u r s i v o A u x ∗/
void
/∗
int
int
int
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
349
Ordenação externa: intercalação balanceada múltipla
n
Interc.
Interc.
Interc.
iter.
recur.1
recur.2
------------------------------------------------------------------------------------------------16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
131072
I
I
I
I
Faça a intercalação múltipla dos arquivos f1 , f2 , f3 , ... .
Obs.: Se o número nf de arquivos fi é razoavelmente grande (mais que 5 a
10), pode ser usada uma fila de prioridades de tamanho nf .
0.004
0.004
0.009
0.017
0.039
0.085
0.151
0.322
0.703
1.510
3.279
7.133
15.489
33.404
0.003
0.005
0.009
0.016
0.035
0.074
0.124
0.268
0.573
1.233
2.605
5.520
11.546
24.359
0.005
0.005
0.014
0.016
0.033
0.072
0.130
0.279
0.604
1.290
2.721
5.769
12.192
26.042
0.005
0.010
0.021
0.053
0.107
0.218
0.371
0.805
1.646
3.570
7.442
15.563
32.772
68.350
0.004
0.006
0.010
0.018
0.046
0.083
0.144
0.302
0.654
1.404
2.968
6.189
13.167
27.769
Desafio: programar esta versão.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
I
I
I
I
I
I
Algoritmos de ordenação
Quicksort
I
I
Leia o máximo número de registros de f que cabem na memória num
vetor v.
Ordene v usando um dos algoritmos de ordenação internos (por
exemplo, quicksort).
Escreva o conteúdo de v em arquivo fi .
i=i+1
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
0.005
0.003
0.003
0.009
0.004
0.007
0.031
0.009
0.016
0.106
0.030
0.050
0.404
0.106
0.179
1.685
0.450
0.674
5.969
1.336
2.079
21.301
5.282
8.136
84.809
21.273
32.121
338.462
84.498
127.803
1351.672
340.743
514.325
5390.648 1366.402 2054.017
21565.843 5450.148 8213.796
89281.419 21772.341 32872.943
Heapsort
Algoritmos de ordenação
350
Ordenação digital ou por distribuição (radix sort)
i=1
Enquanto há dados em f :
I
Selecao
A última coluna corresponde a uma implementação otimizada do
algoritmo de intercalação recursivo que evita alocação e liberação de
espaço em cada chamada.
Passos do algoritmo, dado um arquivo f :
I
(2^4)
(2^5)
(2^6)
(2^7)
(2^8)
(2^9)
(2^10)
(2^11)
(2^12)
(2^13)
(2^14)
(2^15)
(2^16)
(2^17)
Insercao
I
I
I
Bubble
351
O algoritmo baseia-se em procedimentos que eram utilizados para
ordenar cartões perfurados com máquinas classificadoras.
A chave de cada registro de informação é tratada como uma cadeia
de caracteres (ou um número numa base conveniente b) de
comprimento m.
Os registros são distribuı́dos em b sequências, conforme o último
caractere da chave (mantendo a ordem relativa original).
As b sequências são (conceitualmente) concatenadas em ordem
crescente do caractere usado na distribuição.
Os dois passos anteriores são repetidos para o penúltimo, o
antepenúltimo, etc, caractere da chave.
Após m distribuições, o vetor estará ordenado.
O número de operações é no mı́nimo da ordem de O(nm),
dependendo da implementação.
O algoritmo é estável.
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
Algoritmos de ordenação
352
Ordenação digital (cont.)
Exemplo (m = 2):
Vetor original:
07
49
73
58
30
72
44
78
23
09
40
65
92
42
87
03
27
29
40
12
Distribuiç~
ao pelo último dı́gito:
0:
30
1:
40
40
|
|
2:
3:
72
92
42
12
|
73
4:
23
03
|
44
5:
|
65
6:
|
7:
|
8:
07
87
27
|
58
FIM
9:
78
|
49
09
29
Distribuiç~
ao pelo penúltimo dı́gito:
0:
03
1:
07
09
|
12
2:
|
23
3:
27
29
|
30
4:
|
40
5:
40
42
44
49
|
58
6:
|
65
7:
|
72
73
78
|
8:
9:
87 |
92
Resultado:
03
07
09
12
23
27
29
30
40
40
42
44
49
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
58
65
72
73
78
87
Algoritmos de ordenação
92
353
c
2011
T. Kowaltowski Estruturas de Dados e Técnicas de Programação
FIM
354