Escolar Documentos
Profissional Documentos
Cultura Documentos
em linguagem C
Paulo Feolo
Instituto de Matemtica e Estatstica
Universidade de So Paulo
Campus/Elsevier
.
Algoritmos em linguagem C
Paulo Feolo
editora Campus/Elsevier, 2009
www.ime.usp.br/pf/algoritmos-livro/
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 2 / 162
Cincia da computao no a cincia dos computadores,
assim como a astronomia no a cincia dos telescpios.
E. W. Dijkstra
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 3 / 162
Leiaute
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 4 / 162
Leiaute Bom
Bom leiaute
int Funcao (int n, int v[]) {
int i, j;
i = 0;
while (i < n) {
if (v[i] != 0)
i = i + 1;
else {
for (j = i + 1; j < n; j++)
v[j-1] = v[j];
n = n - 1;
}
}
return n;
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 5 / 162
Leiaute Mau
Mau leiaute
int Funcao (int n, int v[]) {
int i, j;
i = 0;
while (i < n) {
if (v[i] != 0)
i = i + 1;
else {
for (j = i + 1; j < n; j++)
v[j-1] = v[j];
n = n - 1;
}
}
return n;
}
Use fonte de espaamento fixo!
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 6 / 162
Leiaute Mau
Pssimo leiaute
int Funcao ( int n,int v[] ){
int i,j;
i=0;
while(i<n){
if(v[i] !=0)
i= i +1;
else
{
for (j=i+1;j<n;j++)
v[j-1]=v[j];
n =n- 1;
}
}
return n;
}
Seja consistente!
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 7 / 162
Leiaute Compacto
Um bom leiaute compacto
int Funcao (int n, int v[]) {
int i, j;
i = 0;
while (i < n) {
if (v[i] != 0) i = i + 1;
else {
for (j = i + 1; j < n; j++) v[j-1] = v[j];
n = n - 1; } }
return n; }
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 8 / 162
Leiaute Regras
Regras
Use as regras adotadas por todos os jornais, revistas e livros:
bla bla bla
bla = bla
bla <= bla
bla; bla
bla) bla;
bla {
while (bla
if (bla
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 9 / 162
Leiaute Enfeitado
Leiaute enfeitado
int Funo (int n, int v[]) {
int i, j;
i = 0;
while (i < n) {
if (v[i] != 0)
i = i + 1;
else {
for (j = i + 1; j < n; j++)
v[j-1] = v[j];
n = n - 1;
}
}
return n;
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 10 / 162
Leiaute O que eles dizem
Devemos mudar nossa atitude tradicional em relao construo de programas.
Em vez de imaginar que nossa principal tarefa
instruir o computador sobre o que ele deve fazer,
vamos imaginar que nossa principal tarefa
explicar a seres humanos o que queremos que o computador faa.
D. E. Knuth
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 11 / 162
Documentao
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 12 / 162
Documentao O que versus como
suporemos 0 k n 1
se k = n ento insere no m
quando n vale 0
i j
etc.
contedo da clula:
c.contedo
p-
>
contedo
0 1 2 3 4 5
d 2 3 1 0 1 6
O vetor d d as distncias da cidade 3 a cada uma das demais.
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 60 / 162
Filas Distncias em uma rede
Algoritmo das distncias
Recebe matriz A que representa as interligaes entre cidades 0, 1, . . . , n 1:
h uma estrada de x a y se e somente se A[x][y] = 1.
Devolve um vetor d tal que d[x] a distncia da cidade o cidade x.
int *Distncias (int **A, int n, int o) {
int *d, x, y;
int *f, s, t;
d = malloc (n * sizeof (int));
for (x = 0; x < n; x++) d[x] = -1;
d[o] = 0;
f = malloc (n * sizeof (int));
processo iterativo
free (f);
return d;
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 61 / 162
Filas Distncias em uma rede
processo iterativo
s = 0; t = 1; f[s] = o; /* o entra na fila */
while (s < t) {
x = f[s++]; /* x sai da fila */
for (y = 0; y < n; y++)
if (A[x][y] == 1 && d[y] == -1) {
d[y] = d[x] + 1;
f[t++] = y; /* y entra na fila */
}
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 62 / 162
Filas Distncias em uma rede
Invariantes (antes de cada comparao s < t)
1. para cada cidade v em f[0 . . t1]
existe um caminho de comprimento d[v] de o a v
cujas cidades esto todas em f[0 . . t1]
2. para cada cidade v de f[0 . . t1]
todo caminho de o a v tem comprimento d[v]
3. toda estrada que comea em f[0 . . s1] termina em f[0 . . t1]
Conseqncia
Para cada v em f[0 . . t1], o nmero d[v] a distncia de o a v.
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 63 / 162
Filas Distncias em uma rede
Para provar invariantes 1 a 3, precisamos de mais dois invariantes:
4. d[f[s]] d[f[s+1]] d[f[t1]]
5. d[f[t1]] d[f[s]] + 1
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 64 / 162
Filas Implementao circular
Implementao circular da la
0 t s N-1
444 555 666 111 222 333
uma la f[s..t-1]
Remove elemento da la
x = f[s++];
if (s == N) s = 0;
Insere y na la
f[t++] = y;
if (t == N) t = 0;
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 65 / 162
Filas Implementao em lista encadeada
Fila implementada em lista encadeada
typedef struct cel {
int valor;
struct cel *seg;
} clula;
Decises de projeto
ltima clula: m da la
Fila vazia
clula *s, *t; /* s aponta primeiro elemento da fila */
s = t = NULL; /* t aponta ltimo elemento da fila */
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 66 / 162
Filas Implementao em lista encadeada
Remove elemento da la
Recebe endereos es e et das variveis s e t respectivamente.
Supe que la no est vazia e remove um elemento da la.
Devolve o elemento removido.
int Remove (clula **es, clula **et) {
clula *p;
int x;
p = *es;
/* p aponta o primeiro elemento da fila */
x = p-
>
valor;
*es = p-
>
seg;
free (p);
if (*es == NULL) *et = NULL;
return x;
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 67 / 162
Filas Implementao em lista encadeada
Insere elemento na la
Recebe endereos es e et das variveis s e t respectivamente.
Insere um novo elemento com valor y na la.
Atualiza os valores de s e t.
void Insere (int y, clula **es, clula **et) {
clula *nova;
nova = malloc (sizeof (clula));
nova-
>
valor = y;
nova-
>
seg = NULL;
if (*et == NULL) *et = *es = nova;
else {
(*et)-
>
seg = nova;
*et = nova;
}
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 68 / 162
Pilhas
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 69 / 162
Pilhas Implementao em vetor
Pilha implementada em vetor
0 t N-1
111 222 333 444 555 666 777
uma pilha p[0..t-1]
Remove elemento da pilha
x = p[--t]; /* t -= 1; x = p[t]; */
Insere y na pilha
p[t++] = y; /* p[t] = y; t += 1; */
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 70 / 162
Pilhas Parnteses e chaves
Aplicao: parnteses e chaves
0 j n
se j = 0 ento x v[0]
no mximo n
2
unidades de tempo
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 93 / 162
Algoritmo Mergesort
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 94 / 162
Mergesort Problema auxiliar
Problema principal
Rearranjar os elementos de um vetor v[0 . . n1]
de tal modo que ele que crescente,
ou seja, de modo que v[0] v[1] v[n1].
Problema auxiliar: intercalao
Rearranjar v[p . . r1] em ordem crescente
sabendo que v[p . . q1] e v[q . . r1] so crescentes.
p q1 q r1
111 333 555 555 777 999 999 222 444 777 888
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 95 / 162
Mergesort Intercalao de vetores ordenados
Algoritmo de intercalao
Recebe vetores crescentes v[p . . q1] e v[q . . r1]
e rearranja v[p . . r1] em ordem crescente.
void Intercala (int p, int q, int r, int v[]) {
int i, j, k, *w;
w = malloc ((r-p) * sizeof (int));
i = p; j = q; k = 0;
while (i < q && j < r) {
if (v[i] <= v[j]) w[k++] = v[i++];
else w[k++] = v[j++];
}
while (i < q) w[k++] = v[i++];
while (j < r) w[k++] = v[j++];
for (i = p; i < r; i++) v[i] = w[i-p];
free (w);
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 96 / 162
Mergesort Intercalao de vetores ordenados
Consumo de tempo do algoritmo Intercala
aproximadamente log
2
n rodadas
total: n log
2
n unidades de tempo
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 100 / 162
Mergesort Algoritmo principal
Verso iterativa
void MergesortI (int n, int v[]) {
int p, r, b = 1;
while (b < n) {
p = 0;
while (p + b < n) {
r = p + 2*b;
if (r > n) r = n;
Intercala (p, p + b, r, v);
p = p + 2*b;
}
b = 2*b;
}
}
0 p p+b p+2b n1
111 999 222 999 333 888 444 777 555 666 555
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 101 / 162
Algoritmo Heapsort
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 102 / 162
Heapsort Heap
Problema
Rearranjar os elementos de um vetor v[0 . . n1]
em ordem crescente.
Denio
Um max-heap um vetor v[1 . . m] tal que v[
1
2
f
] v[f]
para f = 2, 3, . . . , m.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
999 888 666 333 777 555 555 333 222 111 444 111 222 444 111
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 103 / 162
Heapsort Heap
1
2 3
4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 104 / 162
Heapsort Algoritmo auxiliar 1
Algoritmo auxiliar 1: insero em um heap
Transforma v[1 . . m+1] em max-heap supondo que v[1 . . m] max-heap.
void InsereEmHeap (int m, int v[]) {
int f = m+1;
while /*X*/ (f > 1 && v[f/2] < v[f]) {
int t = v[f/2]; v[f/2] = v[f]; v[f] = t;
f = f/2;
}
}
invariante no pto X: v[
1
2
i
consumo: log
2
(m + 1) unidades de tempo
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 105 / 162
Heapsort Algoritmo auxiliar 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14
98 97 96 95 94 93 92 91 90 89 87 86 85 99
98 97 96 95 94 93 99 91 90 89 87 86 85 92
98 97 99 95 94 93 96 91 90 89 87 86 85 92
99 97 98 95 94 93 96 91 90 89 87 86 85 92
Transforma v[1 . . 14] em max-heap
supondo que v[1 . . 13] max-heap.
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 106 / 162
Heapsort Algoritmo auxiliar 2
Algoritmo auxiliar 2
Transforma quase-max-heap v[1 . . m] em max-heap.
void SacodeHeap (int m, int v[]) {
int t, f = 2;
while /*X*/ (f <= m) {
if (f < m && v[f] < v[f+1]) ++f;
if (v[f/2] >= v[f]) break;
t = v[f/2]; v[f/2] = v[f]; v[f] = t;
f *= 2;
}
}
v[1 . . m] quase-max-heap se v[
1
2
f
] v[f] para f = 4, 5, . . . , m
invariante no ponto X: v[
1
2
i
consumo: log
2
m unidades de tempo
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 107 / 162
Heapsort Algoritmo principal
Algoritmo Heapsort
Rearranja vetor v[1 . . n] de modo que ele que crescente.
void Heapsort (int n, int v[]) {
int m;
for (m = 1; m < n; m++)
InsereEmHeap (m, v);
for (m = n; /*X*/ m > 1; m--) {
int t = v[1]; v[1] = v[m]; v[m] = t;
SacodeHeap (m-1, v);
}
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 108 / 162
Heapsort Algoritmo principal
Invariantes no ponto X
v[1 . . m] um max-heap
v[1 . . m] v[m+1 . . n]
p j k r
p j k r
c c c > c > c > c ? ? ? = c
j k
c c c c > c > c > c > c > c = c
j
c c c c = c > c > c > c > c > c
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 114 / 162
Quicksort Subproblema da separao
j k
c c c c > c > c > c > c > c = c
ltima passagem pelo ponto A
j
c c c c = c > c > c > c > c > c
resultado nal
Consumo de tempo do algoritmo Separa
proporcional ao nmero de elementos do vetor
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 115 / 162
Quicksort Algoritmo principal
Algoritmo Quicksort
Rearranja o vetor v[p . . r], com p r + 1,
de modo que ele que em ordem crescente.
void Quicksort (int p, int r, int v[]) {
int j;
if (p < r) {
j = Separa (p, r, v);
Quicksort (p, j - 1, v);
Quicksort (j + 1, r, v);
}
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 116 / 162
Quicksort Algoritmo principal
Consumo de tempo do Quicksort
no pior caso: n
2
unidades de tempo
em mdia: nlog
2
n unidades de tempo
n := r p + 1
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 117 / 162
Quicksort Altura da pilha de execuo
Quicksort com controle da altura da pilha de execuo
Cuida primeiro do menor dos subvetores v[p . . j1] e v[j+1 . . r].
void QuickSortP (int p, int r, int v[]) {
int j;
while (p < r) {
j = Separa (p, r, v);
if (j - p < r - j) {
QuickSortP (p, j - 1, v);
p = j + 1;
} else {
QuickSortP (j + 1, r, v);
r = j - 1;
}
}
}
Altura da pilha de execuo: log
2
n
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 118 / 162
Algoritmos
de enumerao
Enumerar = fazer uma lista
de todos os objetos de um determinado tipo
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 119 / 162
Algoritmos de enumerao Enumerao de subseqncias
Problema
Fazer uma lista, sem repeties, de todas as subseqncias de 1, 2, . . . , n.
1
1 2
1 2 3
1 2 3 4
1 2 4
1 3
1 3 4
1 4
2
2 3
2 3 4
2 4
3
3 4
4
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 120 / 162
Algoritmos de enumerao Ordem lexicogrca
Ordem lexicogrca de seqncias
r
1
, r
2
, . . . , r
j
precede s
1
, s
2
, . . . , s
k
se
1. j < k e r
1
, . . . , r
j
= s
1
, . . . , s
j
ou
2. existe i tal que r
1
, . . . , r
i1
= s
1
, . . . , s
i1
e r
i
< s
i
Algoritmo de enumerao em ordem lexicogrca
Recebe n 1 e imprime todas as subseqncias no-vazias de 1, 2, . . . , n
em ordem lexicogrca.
void SubseqLex (int n) {
int *s, k;
s = malloc ((n+1) * sizeof (int));
processo iterativo
free (s);
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 121 / 162
Algoritmos de enumerao Ordem lexicogrca
processo iterativo
s[0] = 0; k = 0;
while (1) {
if (s[k] < n) {
s[k+1] = s[k] + 1;
k += 1;
} else {
s[k-1] += 1;
k -= 1;
}
if (k == 0) break;
imprima (s, k);
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 122 / 162
Algoritmos de enumerao Ordem lexicogrca
Invariante
Cada iterao comea com subseqncia s
1
, s
2
, . . . , s
k
de 1, 2, . . . , n.
k
0 1 2 3 4 5 6 7
0 2 4 5 7 8 ? ?
Vetor s no incio de uma iterao
de SubseqLex com n = 7.
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 123 / 162
Algoritmos de enumerao Ordem lexicogrca
Verso recursiva
void SubseqLex2 (int n) {
int *s;
s = malloc ((n+1) * sizeof (int));
SseqR (s, 0, 1, n);
free (s);
}
void SseqR (int s[], int k, int m, int n) {
if (m <= n) {
s[k+1] = m;
imprima (s, k+1);
SseqR (s, k+1, m+1, n); /* inclui m */
SseqR (s, k, m+1, n); /* no inclui m */
}
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 124 / 162
Algoritmos de enumerao Ordem lexicogrca especial
Ordem lexicogrca especial
r
1
, r
2
, . . . , r
j
precede s
1
, s
2
, . . . , s
k
se
1. j > k e r
1
, . . . , r
k
= s
1
, . . . , s
k
ou
2. existe i tal que r
1
, . . . , r
i1
= s
1
, . . . , s
i1
e r
i
< s
i
1 2 3 4
1 2 3
1 2 4
1 2
1 3 4
1 3
1 4
1
2 3 4
2 3
2 4
2
3 4
3
4
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 125 / 162
Algoritmos de enumerao Ordem lexicogrca especial
Algoritmo de enumerao em ordem lexicogrca especial
Recebe n 1 e imprime, em ordem lexicogrca especial,
todas as subseqncias no-vazias de 1, 2, . . . , n.
void SubseqLexEsp (int n) {
int *s, k;
s = malloc ((n+1) * sizeof (int));
processo iterativo
free (s);
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 126 / 162
Algoritmos de enumerao Ordem lexicogrca especial
processo iterativo
s[1] = 0; k = 1;
while (1) {
if (s[k] == n) {
k -= 1;
if (k == 0) break;
} else {
s[k] += 1;
while (s[k] < n) {
s[k+1] = s[k] + 1;
k += 1;
}
}
imprima (s, k);
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 127 / 162
Algoritmos de enumerao Ordem lexicogrca especial
Verso recursiva
Recebe n 1 e imprime todas as subseqncias de 1, 2, . . . , n
em ordem lexicogrca especial.
void SubseqLexEsp2 (int n) {
int *s;
s = malloc ((n+1) * sizeof (int));
SseqEspR (s, 0, 1, n);
free (s);
}
continua. . .
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 128 / 162
Algoritmos de enumerao Ordem lexicogrca especial
continuao
Recebe um vetor s[1 . . k] e imprime, em ordem lexicogrca especial,
todas as seqncias da forma s[1], . . . , s[k], t[k+1], . . .
tais que t[k+1], . . . uma subseqncia de m, m+1, . . . , n.
Em seguida, imprime a seqncia s[1], . . . , s[k].
void SseqEspR (int s[], int k, int m, int n) {
if (m > n) imprima (s, k);
else {
s[k+1] = m;
SseqEspR (s, k+1, m+1, n); /* inclui m */
SseqEspR (s, k, m+1, n); /* no inclui m */
}
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 129 / 162
Algoritmos de enumerao Ordem lexicogrca especial
2 4 7 8 9
2 4 7 8
2 4 7 9
2 4 7
2 4 8 9
2 4 8
2 4 9
2 4 9
2 4
Resultado de SseqEspR (s,2,7,9)
supondo s[1] = 2 e s[2] = 4.
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 130 / 162
Busca de palavras
em um texto
Problema:
Encontrar as ocorrncias de a[1 . . m] em b[1 . . n].
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 131 / 162
Busca de palavras Exemplos
a l g o r t i m o
O s a l g o r t i m o s d e o r d e n a o
3 1 4 1 5 9
3 1 3 1 4 3 1 4 1 3 1 4 1 5 9 3 1 4 1 5 9 2 6 3 1 4
T A C T A
G T A G T A T A T A T A T A T A C T A C T A G T A G
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 132 / 162
Busca de palavras O problema
Denies
pr-processamento: m
2
unidades de tempo
-
`
`
`
-
`
`
`
-
`
`
`
`
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 142 / 162
rvores binrias Denio
Estrutura de um n
struct cel {
int contedo;
struct cel *esq;
struct cel *dir;
};
typedef struct cel n;
999
contedo
esq dir
r
r
e
e
e
typedef n *rvore;
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 143 / 162
rvores binrias Varredura esquerda-raiz-direita
Varredura esquerda-raiz-direita
Visite
depois a raiz
-
`
`
`
-
`
`
`
-
`
`
`
`
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 144 / 162
rvores binrias Varredura esquerda-raiz-direita
Algoritmo de varredura e-r-d
Recebe uma rvore binria r
e imprime o contedo de seus ns em ordem e-r-d.
void Erd (rvore r) {
if (r != NULL) {
Erd (r-
>
esq);
printf ("%d\n", r-
>
contedo);
Erd (r-
>
dir);
}
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 145 / 162
rvores binrias Varredura esquerda-raiz-direita
Verso iterativa
void ErdI (rvore r) {
n *p[100], *x;
int t = 0;
x = r;
while (x != NULL || t > 0) {
/* o topo da pilha p[0..t-1] est em t-1 */
if (x != NULL) {
p[t++] = x;
x = x-
>
esq;
}
else {
x = p[--t];
printf ("%d\n", x-
>
contedo);
x = x-
>
dir;
}
}
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 146 / 162
rvores binrias Altura
Altura
-
`
`
`
-
`
`
`
-
`
`
-
`
`
-
h = log
2
12 = 3
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 147 / 162
rvores binrias Altura
Algoritmo da altura
Devolve a altura da rvore binria r.
int Altura (rvore r) {
if (r == NULL)
return -1; /* a altura de uma rvore vazia -1 */
else {
int he = Altura (r-
>
esq);
int hd = Altura (r-
>
dir);
if (he < hd) return hd + 1;
else return he + 1;
}
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 148 / 162
rvores binrias N seguinte
Estrutura de n com campo pai
struct cel {
int contedo;
struct cel *pai;
struct cel *esq;
struct cel *dir;
};
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 149 / 162
rvores binrias N seguinte
Algoritmo do n seguinte
Recebe um n x de uma rvore binria cujos ns tm campo pai
e devolve o (endereo do) n seguinte na ordem e-r-d.
A funo supe que x = NULL.
n *Seguinte (n *x) {
if (x-
>
dir != NULL) {
n *y = x-
>
dir;
while (y-
>
esq != NULL) y = y-
>
esq;
return y;
}
while (x-
>
pai != NULL && x-
>
pai-
>
dir == x)
x = x-
>
pai;
return x-
>
pai;
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 150 / 162
rvores binrias
de busca
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 151 / 162
rvores de busca Denio
Estrutura de um n
struct cel {
int chave;
int contedo;
struct cel *esq;
struct cel *dir;
};
typedef struct cel n;
rvore de busca: denio
E.chave X.chave D.chave
para todo n X, todo n E na subrvore esquerda de X
e todo n D na subrvore direita de X
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 152 / 162
rvores de busca Busca
Algoritmo de busca
Recebe k e uma rvore de busca r.
Devolve um n cuja chave k ou devolve NULL se tal n no existe.
n *Busca (rvore r, int k) {
if (r == NULL || r-
>
chave == k)
return r;
if (r-
>
chave > k)
return Busca (r-
>
esq, k);
else
return Busca (r-
>
dir, k);
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 153 / 162
rvores de busca Busca
Verso iterativa
while (r != NULL && r-
>
chave != k) {
if (r-
>
chave > k) r = r-
>
esq;
else r = r-
>
dir;
}
return r;
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 154 / 162
rvores de busca Insero
n *novo;
novo = malloc (sizeof (n));
novo-
>
chave = k;
novo-
>
esq = novo-
>
dir = NULL;
Algoritmo de insero
Recebe uma rvore de busca r e uma folha avulsa novo.
Insere novo na rvore de modo que a rvore continue sendo de busca
e devolve o endereo da nova rvore.
rvore Insere (rvore r, n *novo) {
n *f, *p;
if (r == NULL) return novo;
processo iterativo
return r;
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 155 / 162
rvores de busca Insero
processo iterativo
f = r;
while (f != NULL) {
p = f;
if (f-
>
chave > novo-
>
chave) f = f-
>
esq;
else f = f-
>
dir;
}
if (p-
>
chave > novo-
>
chave) p-
>
esq = novo;
else p-
>
dir = novo;
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 156 / 162
rvores de busca Remoo
Algoritmo de remoo da raiz
Recebe uma rvore no-vazia r, remove a raiz da rvore e
rearranja a rvore de modo que ela continue sendo de busca.
Devolve o endereo da nova raiz.
rvore RemoveRaiz (rvore r) {
n *p, *q;
if (r-
>
esq == NULL) q = r-
>
dir;
else {
processo iterativo
}
free (r);
return q;
}
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 157 / 162
rvores de busca Remoo
processo iterativo
p = r; q = r-
>
esq;
while (q-
>
dir != NULL) {
p = q; q = q-
>
dir;
}
/* q o n anterior a r na ordem e-r-d */
/* p o pai de q */
if (p != r) {
p-
>
dir = q-
>
esq;
q-
>
esq = r-
>
esq;
}
q-
>
dir = r-
>
dir;
P. Feolo (IME-USP) Algoritmos em C Campus/Elsevier 158 / 162
rvores de busca Remoo
Exemplo: antes e depois de RemoveRaiz
s
s s
s s
s s
ss s
s
s s
r
11
2 12
1 4
3
p
6
5
q
10
f
8
7 9
s
s s
s s
s s
ss s
s s
q
10
2 12
1 4
3
p
6
5
f
8
7 9