Escolar Documentos
Profissional Documentos
Cultura Documentos
de Ordenação
Sedgewick: Capítulo 6
IAED, 2014/2015
Algoritmos Elementares de Ordenação
• Selection Sort
• Insertion Sort
• Bubble Sort
• Shell Sort
5 IAED, 2014/2015
Motivação
• Razões pedagógicas
– Bom exemplo para aprender terminologia e contexto dos
problemas a codificar e por vezes suficiente
– Alguns são fáceis de generalizar para algoritmos mais eficientes
ou para melhorar o desempenho de outros algoritmos
6 IAED, 2014/2015
Análise de Desempenho
7 IAED, 2014/2015
Algoritmo Estável
8 IAED, 2014/2015
Algoritmo Interno
9 IAED, 2014/2015
Algoritmos de Ordenação - Implementação
int a[]
9 16 10
1 15
2 3 8
4 5 1
7 7 10
8 13 11 13
4 15
2 18 6
l r
10 IAED, 2014/2015
Algoritmos de Ordenação - Implementação
int main() {
int i, a[]={10,9,8,7,6,5,4,3,2,1};
sort(a, 0, 9);
return 0;
}
11 IAED, 2014/2015
Algoritmos de Ordenação – outro exemplo
#define N 10000
Número aleatório Número aleatório
int main() { (int) entre 0 e 999 (float) entre 0 e 1
int i, a[N];
sort(a, 0, N-1);
Resta-nos definir a
for (i = 0; i < N; i++) função sort
printf("%3d ", a[i]);
printf("\n");
return 0;
}
12 IAED, 2014/2015
Selection Sort
l
• Para cada elemento i entre as
posições l e r
– Procura o menor elemento entre i e r
– Se o menor valor — guardado na
posição min — for menor que o valor
guardado na posição i,
• troca o a[i] com o a[min]
13 IAED, 2014/2015
Selection Sort
9 16 1 2 3 8 5 10 7 13 11 4 15 18 6
l i min r
troca o a[i] com o a[min]
14 IAED, 2014/2015
Selection Sort
9 16 1 2 3 4 5 10 7 13 11 8 15 18 6
l i min r
troca o a[i] com o a[min]
15 IAED, 2014/2015
Selection Sort
9 16 1 2 3 4 5 10 7 13 11 8 15 18 6
l i r
16 IAED, 2014/2015
Exercício
• Considere o seguinte vector
v[ ] = {72, 29, 38, 22, 60, 2}
Indique o conteúdo de v no final de cada passo do algoritmo
selection sort.
Inicio: 72 29 38 22 60 2
Passo 1: 2 29 38 22 60 72
Passo 2: 2 22 38 29 60 72
Passo 3: 2 22 29 38 60 72
Passo 4: 2 22 29 38 60 72
Final: 2 22 29 38 60 72
17 IAED, 2014/2015
Selection Sort
20 IAED, 2014/2015
Algoritmos de Ordenação – Abstrações Úteis
Item a[]
9 16 10
1 15
2 3 8
4 5 1
7 7 10
8 13 11 13
4 15
2 18 6
l r
21 IAED, 2014/2015
Selection Sort
22 IAED, 2014/2015
Algoritmos de Ordenação – Abstrações Úteis
#define N 10000
typedef int Item;
#define key(A) (A)
#define less(A, B) (key(A) < key(B))
#define exch(A, B) { Item t = A; A = B; B = t; }
#define compexch(A, B) if (less(B, A)) exch(A, B)
int main() {
int i, a[N];
selection(a, 0, N-1);
(...)
}
23 IAED, 2014/2015
Exercício
• Considere o seguinte vector
a[ ] = {22, 33, 1, 10, 11, 2}
Indique o conteúdo de a depois de 3 iterações do algoritmo
selection sort.
Inicio: 22 33 1 10 11 2
1 33 22 10 11 2
1 2 22 10 11 33
R: 1 2 10 22 11 33
24 IAED, 2014/2015
Selection Sort
• Tempo de execução:
– Comparações: N 2 / 2 , trocas: N
2
– No pior caso é O( N ) , com N = r−l
2
– No melhor caso, é O( N ) , com N = r−l
• O algoritmo é estável?
– Será que a ordem relativa de chaves duplicadas é mantida?
{ 2 2 1 3}
{ 1 2 2 3}
Alterámos a ordem relativa de
25 chaves duplicadas! IAED, 2014/2015
Selection Sort
• Tempo de execução:
– Comparações: N 2 / 2 , trocas: N
2
– No pior caso é O( N ) , com N = r−l
2
– No melhor caso, é O( N ) , com N = r−l
26 IAED, 2014/2015
Insertion Sort (ideia geral)
l r
27 IAED, 2014/2015
Insertion Sort (algoritmo)
9 16 1 3 8 15 5 10 7 13 11 4 2 18 6
l i r
9 16 1 3 5 8 15 10 7 13 11 4 2 18 6
l r
28 IAED, 2014/2015
Exercício
• Considere o seguinte vector
v[ ] = {72, 29, 38, 22, 60, 2}
Indique o conteúdo de no final de cada passo do algoritmo
insertion sort.
Início:
* 72 29 38 22 60 2
*
Passo 1: 29 72 38 22 60 2
*
Passo 2: 29 38 72 22 60 2
Passo 3: 22 29 38 72 60 2
*
Passo 4: 22 29 38 60 72 2
*
Final: 2 22 29 38 60 72
29 IAED, 2014/2015
Insertion Sort
30 IAED, 2014/2015
Insertion Sort
• Tempo de execução:
2
– No pior caso é O( N ) , com N = r−l, i.e. vector já ordenado por
ordem inversa
– No melhor caso é O(N ) , com N = r−l, i.e. vector já ordenado
• Algoritmo é estável
– i.e. ordem relativa de chaves duplicadas é mantida
31 IAED, 2014/2015
Exercício (Verdadeiro ou Falso)
32 IAED, 2014/2015
Exercício (Verdadeiro ou Falso)
l r
34 IAED, 2014/2015
Bubble Sort
35 IAED, 2014/2015
Bubble Sort
36 IAED, 2014/2015
Bubble Sort (direita para a esquerda)
9 16 1 2 3 10 15 4 5 8 7 11 13 18 6
9 16 1 2 3 10 4 15 5 8 7 11 13 18 6
9 16 1 2 3 4 10 15 5 8 7 11 13 18 6
38 IAED, 2014/2015
Bubble Sort (direita para a esquerda
+ condição de paragem)
void bubble(Item a[], int l, int r)
{
int i, j, done;
for (i = l; i < r; i++){
done=1;
for (j = r; j > i; j--)
if (less(a[j], a[j-1])){
exch(a[j-1], a[j]);
XXXXX ;
}
YYYYY;
}
}
39 IAED, 2014/2015
Bubble Sort (direita para a esquerda
+ condição de paragem)
void bubble(Item a[], int l, int r)
{
int i, j, done;
for (i = l; i < r; i++){
done=1;
for (j = r; j > i; j--)
if (less(a[j], a[j-1])){
exch(a[j-1], a[j]);
done=0;
}
YYYYY;
}
}
40 IAED, 2014/2015
Bubble Sort (direita para a esquerda
+ condição de paragem)
void bubble(Item a[], int l, int r)
{
int i, j, done;
for (i = l; i < r; i++){
done=1;
for (j = r; j > i; j--)
if (less(a[j], a[j-1])){
exch(a[j-1], a[j]);
done=0;
}
if (done) break;
}
}
41 IAED, 2014/2015
Exercício
• Considere o seguinte vector
v[ ] = {72, 29, 38, 22, 60, 2}
Indique o conteúdo de v no final 2 passagens do algoritmo
bubble sort (esquerda para a direita).
Primeira passagem: 72 29 38 22 60 2
29 72 38 22 60 2
29 38 72 22 60 2
29 38 22 72 60 2
29 38 22 60 72 2
29 38 22 60 2 72
42 IAED, 2014/2015
Exercício
• Considere o seguinte vector
v[ ] = {72, 29, 38, 22, 60, 2}
Indique o conteúdo de v no final 2 passagens do algoritmo
bubble sort (esquerda para a direita).
Segunda passagem: 29 38 22 60 2 72
29 38 22 60 2 72
29 22 38 60 2 72
29 22 38 60 2 72
29 22 38 2 60 72
29 38 22 60 2 72
43 IAED, 2014/2015
Comparação
• Pior Caso
Selection Insertion Bubble
Comparações N2 / 2 N2 / 2 N2 / 2
Trocas Chaves N N2 / 2 N2 / 2
• Caso Médio
Selection Insertion Bubble
Comparações N2 / 2 N2 / 4 N2 / 2
Trocas Chaves N N2 / 4 N2 / 2
44 IAED, 2014/2015
Comparação
1 15 2 16 3 17 4 18 5 19 11 22 18 2-ordenado
1 2 3 4 5 11 18
15 16 17 18 19 22
49 IAED, 2014/2015
Shell Sort
h=3
19 2 15 18 4 11 17 18 5 1 3 22 16
i
18 2 15 19 4 11 17 18 5 1 3 22 16
i
18 2 15 19 4 11 17 18 5 1 3 22 16
i
18 2 11 19 4 15 17 18 5 1 3 22 16
i
17 2 11 18 4 15 19 18 5 1 3 22 16
i
17 2 11 18 4 15 19 18 5 1 3 22 16
i
50 IAED, 2014/2015
Shell Sort
h=3
17 2 5 18 4 11 19 18 15 1 3 22 16
i
1 2 5 17 4 11 18 18 15 19 3 22 16
i
1 2 5 17 3 11 18 4 15 19 18 22 16
i
1 2 5 17 3 11 18 4 15 19 18 22 16
i
1 2 5 16 3 11 17 4 15 18 18 22 19
i
1 16 17 18 19 3-ordenado
2 3 4 18
5 11 15 22
51 IAED, 2014/2015
Shell Sort - Funcionamento
52 IAED, 2014/2015
Escolha da Sequência de Ordenação
elementos nas posições
pares não são comparados
• Questão difícil de responder com elementos nas
• Propriedades de muitas sequênciasposições
já foramímpares
estudadas
até ao
passo final
• Possível provar que umas melhores que outras
– 1, 4, 13, 40, 121, 364, 1093, 3280, ... (Knuth, 3 N + 1 )
– melhor que 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, ...(Shell, 2i )
Porquê?
– mas pior (20%) que 1, 8, 23, 77, 281, 1073, ... ( 4i +1 + 3 × 2i + 1 )
• Na prática utilizam-se sequências que decrescem
geometricamente para que o número de incrementos
seja logarítmico
• A sequência óptima ainda não foi descoberta
53 IAED, 2014/2015
Shell Sort - Complexidade
54 IAED, 2014/2015
Shell Sort - Avaliação Experimental
N O K G S P I
12500 16 6 6 5 6 6
25000 37 13 11 12 15 10
50000 102 31 30 27 38 26
100000 303 77 60 63 81 58
200000 817 178 137 139 180 126
56 IAED, 2014/2015
Começa com h=1,
gera sequência h: 1 4
depois vai para h=4 e
Exercício 13 40 121 364 1093
pára... Logo o primeiro
3280 ...
valor de h será 4
void shellsort(Item a[], int l, int r) Suponha que a função shellsort é
{ invocada com os seguintes
int i, j, h; argumentos:
for (h=1; h <= (r-l)/9; h = 3*h+1)
;
a = { 16, 8, 4, 19, 20, 5,
for ( ; h > 0; h /= 3)
for (i = l+h; i <= r; i++) {
13, 11, 6, 12 },
int j = i;
l = 0, r = 9
Item v = a[i];
while (j >= l+h && less(v, a[j-h])) Indique qual o conteúdo do vector a
{ durante a execução da função
a[j] = a[j-h]; shellsort após o primeiro valor de h ter
j -= h; sido considerado.
}
a[j] = v;
}
} Agora resta-me aplicar
o insertion sort com
57 h=4. Como faço isso? IAED, 2014/2015
Exercício
h=4
Resultado:
6, 5, 4, 11, 16, 8, 13, 19, 20, 12
58 IAED, 2014/2015
Algoritmos Eficientes
de Ordenação
Sedgewick: Capítulo 6
IAED, 2014/2015
Algoritmos Eficientes de Ordenação
• Quick Sort
• Merge Sort
• Heap Sort
2 IAED, 2014/2015
Quick Sort
IAED, 2014/2015
Quick Sort - Introdução
4 IAED, 2014/2015
Quick Sort - Introdução
5 IAED, 2014/2015
Quick Sort - ideia
3 5 10 8 11 1 2 4 14 13 7
X X X X X P O O O O O
i
6 IAED, 2014/2015
Quick Sort - Partição
pivot
9 16 3 5 10 8 11 1 2 4 14 13 7 18 6
i j
9 16 3 5 10 8 11 1 2 4 14 13 7 18 6
i j
9 16 3 5 4 8 11 1 2 10 14 13 7 18 6
i j
9 16 3 5 4 2 11 1 8 10 14 13 7 18 6
i j
9 16 3 5 4 2 1 11 8 10 14 13 7 18 6
i j
9 16 3 5 4 2 1 7 8 10 14 13 11 18 6
8 IAED, 2014/2015
Quick Sort - Partição
if (r <= l)
return;
i = partition(a, l, r);
quicksort(a, l, i-1);
quicksort(a, i+1, r);
}
11 IAED, 2014/2015
Quick Sort - Recursão
9 16 3 5 4 2 1 7 8 10 14 13 11 18 6
9 16 1
3 5 4 2 1
3 7 8 10 14 13 11 18 6
9 16 1 5
2 4
3 2
5 3
4 7 8 10 14 13 11 18 6
9 16 1 2 3 5
4 4
5 7 8 10 14 13 11 18 6
9 16 1 2 3 4 5 7 8 10 14
11 13 14
11 18 6
9 16 1 2 3 4 5 7 8 10 11 13 14 18 6
9 16 1 2 3 4 5 7 8 10 11 13 14 18 6
9 16 1 2 3 4 5 7 8 10 11 13 14 18 6
12 IAED, 2014/2015
Quick Sort | função partição | Exercício (5 min!!)
Considere a função int partition (Item a[], int l, int r) usada no algoritmo quicksort.
13 IAED, 2014/2015
Quick Sort | função partição | Exercício
• Pivot = v = a[r] = 6
10, 2, -2, 13, 14, -1, 7, 5, 0, 6
i j
• Troco o 10 com o 0
0, 2, -2, 13, 14, -1, 7, 5, 10, 6
i j
• Troco o 13 com o 5
• Troco o 14 com o -1
14 IAED, 2014/2015
Quick Sort | função partição | Exercício
17 IAED, 2014/2015
Quick Sort - Melhorias
19 IAED, 2014/2015
III.c) Considere a função int partition (Item a[], int l, int r) usada no algoritmo
quicksort.
int partition(Item a[], int l, int r) {
int i = l-1, j = r;
Item v = a[r];
while (i < j) {
while (less(a[++i], v)); Exercício
while (less(v, a[--j]))
if (j == l)
break;
if (i < j)
exch(a[i], a[j]);
}
exch(a[i], a[r]);
return i;
}
Esta função recebe o vector a e as posições l e r que definem, respectivamente, os ı́ndices
limite esquerdo e direito do vector a considerar na função. Suponha que a função partition
é invocada com os seguintes argumentos:
a = {8, 1, -2, 10, 12, -7, 7, 11, 0, 5}, l = 0, r = 9
Indique qual o conteúdo do vector a após a execução da função partition e indique o valor
IAED, 2014/2015
de i retornado na ultima linha da função.
8, 1, -2, 10, 12, -7, 7, 11, 0, 5
(o pivot é o 5!)
o iterador i começa por parar no 8 e o j no 0 :
troco o 8 com o 0
0, 1, -2, 10, 12, -7, 7, 11, 8, 5
o iterador i pára no 10 e o j no -7: troco o 10 com o -7
0, 1, -2, -7, 12, 10, 7, 11, 8, 5
o iterador i pára no 12 e o j no -7: como o i>j já não troco
j i
0, 1, -2, -7, 12, 10, 7, 11, 8, 5
Resta-me portanto trocar o a[i] com o pivot, ficando:
resultado : 0, 1, -2, -7, 5, 10, 7, 11, 8, 12
IAED, 2014/2015
Merge Sort - ideia
Partir sucessivamente ao
meio o vector de
elementos a ordenar,
até obtermos vectores
com apenas um elemento
Aplicar sucessivamente o
procedimento de Merge,
para gerar um vector
ordenado a partir de dois
vectores ordenados
23 IAED, 2014/2015
Merge Sort - Merge
ordenado ordenado
9 16 1 3
2 3
5 5 11
8 10
4 7 28 10 7 13 14 18 6
4 11
l m r
Uso um vector
auxiliar + 2 iteradores:
aux 1 3 5 8 10 11 14 13 7 4 2
i j
24 IAED, 2014/2015
Devolve um vector ordenado,
Merge Sort - Merge em a[l..r], dados dois
vectores ordenados em
a[l..m] e a[m+1..r]
Item aux[maxN];
25 IAED, 2014/2015
Merge Sort - Merge
Item aux[maxN];
26 IAED, 2014/2015
Merge Sort - Merge
Item aux[maxN];
27 IAED, 2014/2015
Merge Sort (top-down version)
if (r <= l)
return;
mergesort(a, l, m);
mergesort(a, m+1, r);
merge(a, l, m, r);
}
28 IAED, 2014/2015
Merge Sort
mergesort(a,0,10)
mergesort(a,0,5)
... void mergesort(Item a[],
mergesort(a,6,10)
... int l, int r)
{
int m = (r+l)/2;
if (r <= l)
return;
mergesort(a, l, m);
mergesort(a, m+1, r);
merge(a, l, m, r);
}
29 IAED, 2014/2015
Merge Sort
mergesort(a,0,10)
mergesort(a,0,5)
mergesort(a,0,2) void mergesort(Item a[],
...
mergesort(a,3,5) int l, int r)
...
mergesort(a,6,10) {
mergesort(a,6,8) int m = (r+l)/2;
...
mergesort(a,9,10)
... if (r <= l)
return;
mergesort(a, l, m);
mergesort(a, m+1, r);
merge(a, l, m, r);
}
31 IAED, 2014/2015
Merge Sort
mergesort(a,0,10)
mergesort(a,0,5)
mergesort(a,0,2) void mergesort(Item a[],
mergesort(a,0,1)
mergesort(a,0,0) int l, int r)
mergesort(a,1,1)
mergesort(a,2,2) {
mergesort(a,3,5) int m = (r+l)/2;
mergesort(a,3,4)
mergesort(a,3,3)
mergesort(a,4,4) if (r <= l)
mergesort(a,5,5)
mergesort(a,6,10) return;
mergesort(a,6,8)
mergesort(a,6,7)
mergesort(a,6,6) mergesort(a, l, m);
mergesort(a,7,7) mergesort(a, m+1, r);
mergesort(a,8,8)
mergesort(a,9,10) merge(a, l, m, r);
mergesort(a,9,9)
mergesort(a,10,10) }
32 IAED, 2014/2015
Merge Sort
mergesort(a,0,10)
mergesort(a,0,5)
mergesort(a,0,2) void mergesort(Item a[],
mergesort(a,0,1)
mergesort(a,0,0) int l, int r)
mergesort(a,1,1)
mergesort(a,2,2) {
mergesort(a,3,5) int m = (r+l)/2;
mergesort(a,3,4)
mergesort(a,3,3)
mergesort(a,4,4) if (r <= l)
mergesort(a,5,5)
mergesort(a,6,10) return;
mergesort(a,6,8)
mergesort(a,6,7)
mergesort(a,6,6) mergesort(a, l, m);
mergesort(a,7,7) mergesort(a, m+1, r);
mergesort(a,8,8)
mergesort(a,9,10) merge(a, l, m, r);
mergesort(a,9,9)
mergesort(a,10,10) }
33 IAED, 2014/2015
Merge Sort
0 1 2 3 4 5 6 7 8 9 10
9 16 3 5 10 8 11 1 2 4 14 13 7 18 6
9 16
mergesort(a,0,1) 3 5 10 8 11 1 2 4 14 13 7 18 6
9 16
mergesort(a,0,2) 3 5 10 8 11 1 2 4 14 13 7 18 6
9 16
mergesort(a,3,4) 3 5 10 8 11 1 2 4 14 13 7 18 6
9 16
mergesort(a,3,5) 3 5 10 1 8 11 2 4 14 13 7 18 6
9 16
mergesort(a,0,5) 1 3 5 8 10 11 2 4 14 13 7 18 6
9 16
mergesort(a,6,7) 1 3 5 8 10 11 2 4 14 13 7 18 6
9 16
mergesort(a,6,8) 1 3 5 8 10 11 2 4 14 13 7 18 6
9 16
mergesort(a,9,10) 1 3 5 8 10 11 2 4 14 7 13 18 6
9 16
mergesort(a,6,10) 1 3 5 8 10 11 2 4 7 13 14 18 6
9 16
mergesort(a,0,10)
34
1 2 3 4 5 7 8 10 11 IAED,
13 2014/2015
14 18 6
Merge Sort - Complexidade
• Tempo de execução:
• É estável
35 IAED, 2014/2015
II.b) Considere o seguinte função na linguagem C:
Exercício
void merge(int a[], int l, int m, int r)
{
int i, j, k;
int aux[MAXN];
Qual a expressão que deve ser coloca em XXXXXXXX? Note que esta função ordena um vector a em que
inicialmente os valores nas posições de 0 a m estão ordenados por ordem crescente e os valores nas
posições de m+1 a r estão também ordenados por ordem crescente Ou seja, dadas duas sequências
de valores
36 ordenados, esta função realiza a união ordenada. IAED, 2014/2015
Qual a expressão
II.b) Considere o seguinte função na linguagem C:
que deve ser
Exercício
void merge(int a[], int l, int m, int inicialmente
r) os valores nas po
{
int i, j, k; posições de m+1 a r estão tam
int aux[MAXN];
de valores ordenados, esta fun
for (i = m+1; i > l; i--)
aux[i-1] = a[i-1];
37
{
posições de m+1 a r estão também ordenados por ordem crescente Ou seja, dadas duas sequências
de valores ordenados, esta função realiza a união ordenada. IAED, 2014/2015
Heap Sort
IAED, 2014/2015
HeapSort (ideia base)
• Podemos pensar no heapsort como um selection sort
mais eficiente.
IAED, 2014/2015
Das árvores aos amontoados (heaps)
20 16 12 11 15 7 6 10 2
40 IAED, 2014/2015
Das árvores aos amontoados (heaps)
16 12
11 15 7 6
10 2
20 16 12 11 15 7 6 10 2
41 IAED, 2014/2015
Amontoado (heap): definição
11 15 7 6
10 2
42 IAED, 2014/2015
Amontoado (heap): definição | Exercício
Lab. 6. Ex. 4:
Quais dos seguintes vectores corresponde a um
amontoado (heap)?
Lab. 6. Ex. 4:
Quais dos seguintes vectores corresponde a um
amontoado (heap)?
Filho direito
0
20
1
2
16 12
3 4 5 6
11 15 7 6
7 8
10 2 20 16 12 11 15 7 6 10 2
0 1 2 3 4 5 6 7 8
45 IAED, 2014/2015
Amontoado: Índices
int parent(int k) {
return ((k+1)/2)-1;
}
int left(int k) {
return 2*k+1;
}
int right(int k) {
return 2*(k+1);
}
46 IAED, 2014/2015
Operações em Amontoados: fixDown
Fixdown (i):
• chamada quando se pretende diminuir a chave de um nó
• confirma se ambos os filhos são menores do que “ele”;
• se não for o caso, troca de posição com o filho maior e
volta a chamar-se para a posição onde o filho maior
estava.
Fixdown (indice i)
verifica se i tem um filho maior que ele
SE i tem um filho maior:
troca i com o filho_maior
Função Fixdown (pos_do_filho_maior)
recursiva
47 IAED, 2014/2015
Operações em Amontoados: fixDown(em C)
void fixDown(Item a[], int l, int r, int k)
{
int ileft, iright, largest=k;
ileft=l+left(k-l);
iright=l+right(k-l);
if (largest!=k){
exch(a[k],a[largest]);
fixDown(a, l, r, largest);
}
}
48 IAED, 2014/2015
Operações em Amontoados: fixDown
• Se tivermos um amontoado...
20
16 12
11 15 7 6
10 2
49 IAED, 2014/2015
Operações em Amontoados: fixDown
16 12
11 15 7 6
10 2
50 IAED, 2014/2015
Operações em Amontoados: fixDown
16
5 12
11 15 7 6
10 2
51 IAED, 2014/2015
Operações em Amontoados: fixDown
16
Será que já é
um
15 12 amontoado?
11 5 7 6
10 2
52 IAED, 2014/2015
Operações em Amontoados: fixDown
16
Será que já é
um
15 12 amontoado?
SIM!!!!
11 5 7 6
10 2
53 IAED, 2014/2015
Operações em Amontoados: buildheap
• Mas como transformar um vector arbitrário num
amontoado?
20
16 12
11 15 7 6
10 2
20 16 12 11 15 7 6 10 2
54 IAED, 2014/2015
Operações em Amontoados: buildheap
buildheap:
• Chama fixDown do último até ao primeiro elemento do
vector até todos os elementos cumprirem a heap condition.
• Uma forma mais rápida de o fazer é começar por chamar o
fixDown ao pai com o índice mais elevado
(K=heapsize/2-1), e a todos os índices<K
55 IAED, 2014/2015
Heapsort
16 12
11 15 7 6
10 20
2 16 12 11 15 7 6 10 20
56 IAED, 2014/2015
void buildheap(Item a[], int l, int r){
int k, heapsize = r-l+1;
FD 16 12
11 15 7 6
10 20
2 16 12 11 15 7 6 10 20
57 IAED, 2014/2015
void buildheap(Item a[], int l, int r){
int k, heapsize = r-l+1;
16 12
20 FD 15 7 6
10 11
2 16 12 20 15 7 6 10 11
58 IAED, 2014/2015
void buildheap(Item a[], int l, int r){
int k, heapsize = r-l+1;
16 12
20 15 7 6
10 11
2 16 12 20 15 7 6 10 11
59 IAED, 2014/2015
void buildheap(Item a[], int l, int r){
int k, heapsize = r-l+1;
16 12
20 15 7 6
10 11
2 16 12 20 15 7 6 10 11
60 IAED, 2014/2015
void buildheap(Item a[], int l, int r){
int k, heapsize = r-l+1;
FD 20 12
16 15 7 6
10 11
2 20 12 16 15 7 6 10 11
61 IAED, 2014/2015
void buildheap(Item a[], int l, int r){
int k, heapsize = r-l+1;
20 12
16 15 7 6
10 11
2 20 12 16 15 7 6 10 11
62 IAED, 2014/2015
void buildheap(Item a[], int l, int r){
int k, heapsize = r-l+1;
2 12
16 15 7 6
10 11
20 2 12 16 15 7 6 10 11
63 IAED, 2014/2015
void buildheap(Item a[], int l, int r){
int k, heapsize = r-l+1;
20
FD 16 12
2 15 7 6
10 11
20 16 12 2 15 7 6 10 11
64 IAED, 2014/2015
void buildheap(Item a[], int l, int r){
int k, heapsize = r-l+1;
20
16 12
11 FD 15 7 6
10 2
20 16 12 11 15 7 6 10 2
65 IAED, 2014/2015
void buildheap(Item a[], int l, int r){
int k, heapsize = r-l+1;
16 12
11 15 7 6
10 2
20 16 12 11 15 7 6 10 2
66 IAED, 2014/2015
Heapsort
20
16 12
11 15 7 6
10 2
20 16 12 11 15 7 6 10 2
67 IAED, 2014/2015
Heapsort
16 12
11 15 7 6
10 20
2 16 12 11 15 7 6 10 20
68 IAED, 2014/2015
Heapsort
16 12
11 15 7 6
10 20
2 16 12 11 15 7 6 10 20
69 IAED, 2014/2015
Heapsort
16 12
11 15 7 6
Encontrámos o
maior elemento
10 20
2 16 12 11 15 7 6 10 20
70 IAED, 2014/2015
Heapsort
16 12
11 15 7 6
10 20
2 16 12 11 15 7 6 10 20
71 IAED, 2014/2015
Heapsort
2 12
11 15 7 6
10 20
16 2 12 11 15 7 6 10 20
72 IAED, 2014/2015
Heapsort
15 12
11 2 7 6
10 20
16 15 12 11 2 7 6 10 20
73 IAED, 2014/2015
Heapsort
• Repetir
16
15 12
11 2 7 6
10 20
16 15 12 11 2 7 6 10 20
74 IAED, 2014/2015
Heapsort
• Repetir
10
15 12
11 2 7 6
16 20
10 15 12 11 2 7 6 16 20
75 IAED, 2014/2015
Heapsort
• Repetir
10
15 12
11 2 7 6
Encontrámos o
2º maior elemento
16 20
10 15 12 11 2 7 6 16 20
76 IAED, 2014/2015
Heapsort
• Repetir
15
11 12
10 2 7 6
16 20
15 11 12 10 2 7 6 16 20
77 IAED, 2014/2015
Heapsort
• Repetir
11 12
10 2 7 15
16 20
6 11 12 10 2 7 15 16 20
78 IAED, 2014/2015
Heapsort
• Repetir
11 12
10 2 7 15
16 20
6 11 12 10 2 7 15 16 20
79 IAED, 2014/2015
Heapsort
• Repetir ...
12
11 7
10 2 6 15
16 20
12 11 7 10 2 6 15 16 20
80 IAED, 2014/2015
Heapsort
• No final
6 7
10 11 12 15
16 20
2 6 7 10 11 12 15 16 20
81 IAED, 2014/2015
Heapsort Começo por transformar o
vector num amontoado
• Receita:
1. Transformamos a[] num amontoado (ver buildheap)
2. Trocamos o ultimo elemento com a raiz, e extraímos esse
elemento do amontoado.
3. Aplicamos o fixDown à raiz
4. Voltamos a 2.
83 IAED, 2014/2015
Exercício
FD 2 17
14 -1 4 8
0 7
84 IAED, 2014/2015
Exercício
2 17
14 -1 4 8
0 7
85 IAED, 2014/2015
Exercício
FD 14 17
2 -1 4 8
0 7
86 IAED, 2014/2015
Exercício
14 17
7 -1 4 8
0 2
87 IAED, 2014/2015
Exercício
FD
• Começo por transformar o vector num amontoado.
10
14 17
7 -1 4 8
0 2
88 IAED, 2014/2015
Exercício
FD
• Começo por transformar o vector num amontoado.
FD
17
14 10
7 -1 4 8
0 2
89 IAED, 2014/2015
Exercício
17
14 10
7 -1 4 8
1. Trocamos o ultimo elemento
0 2 com a raiz, e extraímos esse
elemento do amontoado.
2. Aplicamos o fixDown à raiz
3. Voltamos a 1.
90 IAED, 2014/2015
Exercício
14 10
7 -1 4 8
1. Trocamos o ultimo elemento
0 17 com a raiz, e extraímos esse
elemento do amontoado.
2. Aplicamos o fixDown à raiz
3. Voltamos a 1.
91 IAED, 2014/2015
Exercício
14
7 10
2 -1 4 8
1. Trocamos o ultimo elemento
0 17 com a raiz, e extraímos esse
elemento do amontoado.
2. Aplicamos o fixDown à raiz
3. Voltamos a 1.
92 IAED, 2014/2015
Exercício
7 10
2 -1 4 8
1. Trocamos o ultimo elemento
14 17 com a raiz, e extraímos esse
elemento do amontoado.
2. Aplicamos o fixDown à raiz
3. Voltamos a 1.
93 IAED, 2014/2015
Exercício
10
7 8
2 -1 4 0
14 17
94 IAED, 2014/2015
Exercício
10
7 8
2 -1 4 0
14 17
95 IAED, 2014/2015
Heapsort - Complexidade
• Não é estável
96 IAED, 2014/2015
Avaliação Experimental
97 IAED, 2014/2015
Ordenação por Comparação
K&R: Capítulo 5
IAED, 2014/2015
Ponteiros e Tabelas
• Ponteiros e endereços
• Ponteiros e argumentos de funções
• Ponteiros e tabelas
• Alocação dinâmica de memória
• Aritmética de ponteiros
• Tabelas de ponteiros e ponteiros para ponteiros
• Tabelas multi-dimensionais
• Inicialização de tabelas de ponteiros
• Argumentos da linha de comandos
2 IAED, 2014/2015
Ponteiros e Endereços
a
3245434
3245435
3245436
3245437
3 IAED, 2014/2015
Ponteiros e Endereços: exemplo
int x = 10;
int *px = &x;
px
x 3245434
3245435
3245436
3245437
Inicializo px com
Declaração de um o endereço de x
ponteiro (operador &)
4 IAED, 2014/2015
O que é
um ponteiro em C ?
5 IAED, 2014/2015
Um ponteiro em C
é
um endereço de memória
6 IAED, 2014/2015
Declaração de ponteiros
• Na sua declaração temos de indicar ao compilador para
que tipo de variável estamos a endereçar.
• Exemplos
char *cptr; /* ponteiro para caracter */
• Exemplos
/* apenas a é um ponteiro*/
int* a, b;
• Exemplos
9 IAED, 2014/2015
Operador &
• Exemplos
10 IAED, 2014/2015
Operador &
11 IAED, 2014/2015
Operador *
• Exemplo:
int a = 43; /* um inteiro inicializado a 43 */
int *iptr; /* ponteiro para inteiro */
int b;
#include <stdio.h>
0
1 1
int main() {
int y, x = 1;
int *px; px
px = &x;
y = *px;
*px = 0;
printf("%d %d\n", x, y);
return 0;
}
13 IAED, 2014/2015
Operadores & e * Declaro dois inteiros,
sendo x=1
• Outro exemplo:
• Declaração do ponteiro
int *x;
– x é um ponteiro para um inteiro
*x = 4;
– o valor 4 é atribuído ao conteúdo da posição de memória apontada
por x
15 IAED, 2014/2015
Utilização de Ponteiros
16 IAED, 2014/2015
Passagem de Parâmetros para Funções
aux = a;
a = b;
b = aux;
}
aux = *a;
*a = *b;
*b = aux;
}
19 IAED, 2014/2015
Ponteiro Nulo / Endereço Zero
• Definido em stdlib.h
– Necessário #include <stdlib.h>
• Na realidade NULL == 0
20 IAED, 2014/2015
Ponteiros e Tabelas
return 0;
}
• a é um ponteiro para a primeira posição da tabela
21 IAED, 2014/2015
Ponteiros e Tabelas
int x[10]; px
int *px = x;
X[0]
22 IAED, 2014/2015
Ponteiros e Tabelas
int x[10]; px
int *px = x;
px++;
X[0]
• Incrementa/decrementa na dimensão
do tipo para o qual aponta
– sizeof(int) neste caso
23 IAED, 2014/2015
Ponteiros e Tabelas
int main() {
int a[6] = {1, 2, 7, 0, 11, 6};
int *pa = a;
return 0;
}
• a é um ponteiro para a primeira posição da tabela
24 IAED, 2014/2015
Ponteiros e Tabelas
25 IAED, 2014/2015
Ponteiros e Tabelas
• então
a[i] é equivalente a *(a+i) V
&a[i] é equivalente a a+i V
a[i] é equivalente a p[i] V
p[i] é equivalente a *(p+i) V
*a ? a é equivalente a p[0] F
a[0] ?
27 IAED, 2014/2015
Ponteiros e Tabelas
28 IAED, 2014/2015
Ponteiros e Tabelas
29 IAED, 2014/2015
Ponteiros e Tabelas
30 IAED, 2014/2015
Ponteiros e Tabelas
31 IAED, 2014/2015
Ponteiros e Tabelas
Porquê?
32 IAED, 2014/2015
Passagem de Parâmetros para Funções II
• Quando fazemos
int a;
scanf(“%d”,&a);
char s[100];
scanf(“%s”,s);
33 IAED, 2014/2015
Passagem de Parâmetros para Funções II
34 IAED, 2014/2015
Endereços de ponteiros
int main() {
int x = 10;
int *px = &x;
int **ppx = &px;
return 0;
}
35 IAED, 2014/2015
Argumentos da Linha de Comandos
36 IAED, 2014/2015
1ª nota
• Ao fazer
int *a;
int *a;
*a=12; /* A evitar!!! */
37 IAED, 2014/2015
2ª nota: Ponteiros para Funções
int main() {
int (*ptr)(int, int);
ptr = soma;
printf("%d\n", (*ptr)(3,4));
return 0;
}
38 IAED, 2014/2015
2ª nota: Ponteiros para Funções (2º exemplo)
• É possível ter ponteiros para funções
• O nome de uma função é um ponteiro para essa função
int modulo(int a) { return a < 0 ? –a : a; }
int dobro(int a) { return a*2; }
K&R: Capítulo 5
IAED, 2014/2015
Sinopse da aula de hoje
2 IAED, 2014/2015
3245434
Pointers in a nutshell
3245435
3 IAED, 2014/2015
3245434
Pointers in a nutshell
3245435
4 IAED, 2014/2015
3245434
Pointers in a nutshell
3245435
5 IAED, 2014/2015
3245434
Pointers in a nutshell
3245435
7 IAED, 2014/2015
IAED, 2012/2013
Um ponteiro em C
é
um endereço de memória
8 IAED, 2014/2015
IAED, 2012/2013
Pointers in a nutshell
aux = a;
a = b;
b = aux;
}
9 IAED, 2014/2015
Pointers in a nutshell
aux = *a;
*a = *b;
*b = aux;
}
10 IAED, 2014/2015
Ponteiro Nulo / Endereço Zero
• Definido em stdlib.h
– Necessário #include <stdlib.h>
• Na realidade NULL == 0
11 IAED, 2014/2015
Pointers in a nutshell
return 0;
}
• a é um ponteiro para a primeira posição da tabela
• pa pode ser alterado; a não pode!
12 IAED, 2014/2015
Pointers in a nutshell
x
int x = 10; px
int *px = &x;
13 IAED, 2014/2015
Pointers in a nutshell
x
int x = 10; px
int *px = &x;
px++;
• Incrementa/decrementa na dimensão
do tipo para o qual aponta
– sizeof(int) neste caso
14 IAED, 2014/2015
Passagem de Parâmetros para Funções
• Quando fazemos
int a;
scanf(“%d”,&a);
char s[100];
scanf(“%s”,s);
15 IAED, 2014/2015
Passagem de Parâmetros para Funções
16 IAED, 2014/2015
Passagem de Parâmetros para Funções
17 IAED, 2014/2015
Endereços de ponteiros
int main() {
int x = 10;
int *px = &x;
int **ppx = &px;
return 0;
}
18 IAED, 2014/2015
Argumentos da Linha de Comandos
19 IAED, 2014/2015
ATENÇÃO!
• Ao fazer
int *a;
int *a;
*a=12; /* A evitar!!!*/
20 IAED, 2014/2015
Ponteiros para Funções
int main() {
int (*ptr)(int, int);
ptr = soma;
printf("%d\n", (*ptr)(3,4));
return 0;
}
21 IAED, 2014/2015
Ponteiros para Funções (2º exemplo)
• É possível ter ponteiros para funções
• O nome de uma função é um ponteiro para essa função
int modulo(int a) { return a < 0 ? –a : a; }
int dobro(int a) { return a*2; }
IAED, 2014/2015
Alocação Dinâmica de Memória
• Alocação estática
int tab[100];
24 IAED, 2014/2015
Alocação Dinâmica de Memória
• Função malloc
void *malloc(size_t size);
• Recebe como argumento o número de bytes
– Tipo size_t representa uma dimensão em bytes
• Devolve um ponteiro (endereço) para o primeiro byte do
bloco de memória contígua alocada
– void * indica um ponteiro para um tipo não especificado
– permite utilização com qualquer tipo de dados
– posteriormente faz-se conversão para o tipo correcto por type cast
int *vec;
vec = (int*) malloc(sizeof(int)*100);
25 IAED, 2014/2015
Alocação Dinâmica de Memória
• Função realloc
void *realloc(void *ptr, size_t size);
28 IAED, 2014/2015
Ponteiros para estruturas
IAED, 2014/2015
Sinopse da aula de hoje
• Pointers in a nutshell
• Estruturas, Funções e apontadores
• Estruturas Auto-Referenciadas
• Exemplo de aplicação:
– Listas ligadas
– uma Pilha
30 IAED, 2014/2015
Declaração de Estruturas (recapitulação)
Ponto centro;
• Manipulação : <variavel>.<membro>
centro.x = 12.3;
centro.y = 5.2;
31 IAED, 2014/2015
Declaração de Estruturas
• Declaração de variável do tipo estrutura:
typedef struct ponto {
double x;
double y;
} Ponto
Ponto centro;
Ponto *pcentro = ¢ro;
• Manipulação : (*<variavel>).<membro>
(*pcentro).x = 12.3;
(*pcentro).y = 5.2;
Mas isto é
32 IAED, 2014/2015
aborrecido!
Declaração de Estruturas (operador ->)
• Declaração de variável do tipo estrutura:
typedef struct ponto {
double x;
double y;
} Ponto
Ponto centro;
Ponto *pcentro = ¢ro;
(*<ponteiro>).<membro> é equiv. a
• Manipulação : <ponteiro>-><membro>
pcentro->x = 12.3;
pcentro->y = 5.2;
33 IAED, 2014/2015
Ponteiros para Estruturas
34 IAED, 2014/2015
Estruturas e Funções
36 IAED, 2014/2015
Estruturas, Funções e Ponteiros
return res;
}
37 IAED, 2014/2015
Estruturas, Funções e Ponteiros
• Exemplo (corrigido):
IAED, 2014/2015
Sinopse
• Pointers in a nutshell
• Estruturas, Funções e apontadores
• Estruturas Auto-Referenciadas: das tabelas às listas
• Exemplo de aplicação:
– Listas ligadas
– uma Pilha
42 IAED, 2014/2015
Tabelas/Vectores
• Colecção de items
– Inteiros, reais, caracteres
– Estruturas
– Tabelas, Ponteiros
int tab[N];
#define N 100
int tab1[N];
int *tab2 = (int *) malloc(N*sizeof(int));
44 IAED, 2014/2015
Tabelas/Vectores
• Vantagens
– Manipulação simples
– Facilidade de acesso ao n-ésimo elemento
• Desvantagens
– Tamanho limitado
– Necessidade de realocar e copiar todos os elementos se
desejar aumentar dimensão da tabela
– Desperdicio de memória
• Alternativa: Listas
head NULL
45 IAED, 2014/2015
O que é uma estrutura auto-referenciada?
1 2 3 4 5 6
NULL
head
IAED, 2014/2015
Ponto da situação e plano da aula
2 IAED, 2014/2015
Ponto da situação e plano da aula
3 IAED, 2014/2015
Ponto da situação e plano da aula
• Função malloc
void *malloc(size_t size);
• Recebe como argumento o número de bytes
– Tipo size_t representa uma dimensão em bytes
• Devolve um ponteiro (endereço) para o primeiro byte do
bloco de memória contígua alocada
– void * indica um ponteiro para um tipo não especificado
– permite utilização com qualquer tipo de dados
– posteriormente faz-se conversão para o tipo correcto por type cast
int *vec;
vec = (int*) malloc(sizeof(int)*100);
5 IAED, 2014/2015
Alocação Dinâmica de Memória
Ponto centro;
Ponto *pcentro = ¢ro;
• Manipulação : (*<variavel>).<membro>
(*pcentro).x = 12.3;
(*pcentro).y = 5.2;
Mas isto é
7 IAED, 2014/2015
aborrecido!
Estruturas & pointers (operador ->)
• Declaração de variável do tipo estrutura:
typedef struct ponto {
double x;
double y;
} Ponto
Ponto centro;
Ponto *pcentro = ¢ro;
(*<ponteiro>).<membro> é equiv. a
• Manipulação : <ponteiro>-><membro>
pcentro->x = 12.3;
pcentro->y = 5.2;
8 IAED, 2014/2015
malloc & estruturas
9 IAED, 2014/2015
Estruturas, Funções e Ponteiros
10 IAED, 2014/2015
Tabelas/Vectores
• Vantagens
– Manipulação simples
– Facilidade de acesso ao n-ésimo elemento
• Desvantagens
– Tamanho limitado
– Necessidade de realocar e copiar todos os elementos se
desejar aumentar dimensão da tabela
– Desperdicio de memória
• Alternativa: Listas
head NULL
11 IAED, 2014/2015
Lista Simplesmente Ligada
• Conjunto de nós
head
NULL
• Cada nó contém
– Informação útil
– Ponteiro para o próximo nó
struct node {
int valor;
struct node *next;
valor next
};
12 IAED, 2014/2015
Lista Simplesmente Ligada
• Conjunto de nós
head
NULL
• Cada nó contém
– Informação útil
– Ponteiro para o próximo nó
struct node {
int valor;
struct node *next;
valor next
};
13 IAED, 2014/2015
Lista Simplesmente Ligada
• Conjunto de nós
head
NULL
• Cada nó contém
– Informação útil
– Ponteiro para o próximo nó
struct node {
char nome[256];
struct node *next;
nome next
};
14 IAED, 2014/2015
Lista Simplesmente Ligada
• Conjunto de nós
head
NULL
• Cada nó contém
– Informação útil T O
H R ‘\0’
– Ponteiro para o próximo nó
struct node {
char *nome;
struct node *next;
nome next
};
15 IAED, 2014/2015
Lista Simplesmente Ligada
• Conjunto de nós
head
NULL
• Cada nó contém
– Informação útil
– Ponteiro para o próximo nó
struct node {
Livro *livro;
struct node *next;
livro next
};
16 IAED, 2014/2015
Lista Simplesmente Ligada
• Conjunto de nós
head
NULL
struct node {
Item item;
struct node *next;
item next
};
17 IAED, 2014/2015
Listas
• Vantagens
– Tamanho ilimitado (limite na memória disponível na máquina)
– Alocação de memória apenas para os elementos que queremos
representar
– Inserção e remoção simples
• Desvantagens
– Mais difícil o acesso ao n-ésimo elemento
18 IAED, 2014/2015
Inserção na Lista de um elemento *t depois de *x
t->next = x->next;
x->next = t;
19 IAED, 2014/2015
Inserção na Lista
t->next = x->next;
x->next = t;
20 IAED, 2014/2015
Remoção do elemento depois de x da Lista
t = x->next;
x->next = t->next;
free(t);
t
free (t)
21 IAED, 2014/2015
Lista Duplamente Ligada
• Conjunto de nós
head NULL
NULL
• Cada nó contém
– Informação útil
– Ponteiro para o próximo nó e para o nó anterior
struct node {
Item item;
struct node *prev, *next;
Item prev next
};
22 IAED, 2014/2015
Exemplo: Pilha Dinâmica de Inteiros
6
top
4
top
top 6
2 top 4
2
NULL A única coisa que
não podemos perder
é o pointer para o
topo da pilha
23 IAED, 2014/2015
Exemplo: Pilha Dinâmica de Inteiros
#include <stdio.h>
#include <stdlib.h>
struct node{
int value;
struct node *next;
}; Variável global
24 IAED, 2014/2015
Exemplo: Pilha Dinâmica de Inteiros
NULL
25 IAED, 2014/2015
Exemplo: Pilha Dinâmica de Inteiros
26 IAED, 2014/2015
Exemplo: Pilha Dinâmica de Inteiros
int pop() /* apaga o topo e retorna o valor apagado */
{
int value;
struct node *old;
if (!is_empty()) {
value = top->value; old top
old 6
old = top;
top = top->next; 4
top
free(old);
return value;
2
}
else
return -1; NULL
}
27 IAED, 2014/2015
Exemplo: Pilha Dinâmica de Inteiros
Problema:
• Como obter o número de elementos da Pilha?
Solução:
• Necessário percorrer toda a Pilha!!
28 IAED, 2014/2015
Utilização de typedef
29 IAED, 2014/2015
Utilização de typedef
30 IAED, 2014/2015
Ponto da situação e plano da aula
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
32 IAED, 2014/2015
Lista de Strings
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
33 IAED, 2014/2015
Criar lista com Argumentos da linha de
comandos
34 IAED, 2014/2015
Criar lista com Argumentos da linha de
comandos
int main(int argc, char* argv[])
{
int i;
link head = NULL;
/* inserir todos os elementos na lista*/
for(i = 1; i < argc; i++)
head = insertEnd(head, argv[i]);
print(head); /* imprime toda a lista*/
/* remover um elemento (lido do stdin) */
scanf("%d", &i);
head = delete(head, argv[i]);
print(head); /* voltamos a imprimir toda a lista */
return 0;
}
35 IAED, 2014/2015
Novo Elemento
Função auxiliar NEW responsável pela alocação de memória de tudo o
que é necessário para um novo nó, i.e., a estrutura e a string.
text next
} x
36 IAED, 2014/2015
Novo Elemento
Função auxiliar NEW responsável pela alocação de memória de tudo o
que é necessário para um novo nó, i.e., a estrutura e a string.
Reservar memória
link NEW(char* text) para o novo nó
{
link x = (link) malloc(sizeof(struct
? node));
x->text =
(char*) malloc(sizeof(char)*(strlen(text)+1));
?
strcpy(x->text, text);
x->next = NULL;
return x;
}
37 IAED, 2014/2015
Novo Elemento
Função auxiliar NEW responsável pela alocação de memória de tudo o
que é necessário para um novo nó, i.e., a estrutura e a string.
Reservar memória
link NEW(char* text) para o novo nó
{
link x = (link) malloc(sizeof(struct node));
x->text =
(char*) malloc(sizeof(char)*(strlen(text)+1));
?
strcpy(x->text, text);
x->next = NULL;
return x;
}
NULL
42 text IAED, 2014/2015
Inserção na Lista
t->next = x->next;
x->next = t;
43 IAED, 2014/2015
Inserção na Lista
t->next = x->next;
x->next = t;
44 IAED, 2014/2015
Inserção no Início (mais fácil)
45 IAED, 2014/2015
Inserção no Início
int main(){
(...)
head = insertBegin(head, “Bolo”);
(...)
}
46 IAED, 2014/2015
Inserção no Fim
47 IAED, 2014/2015
Inserção no Fim
48 IAED, 2014/2015
Procura na Lista
49 IAED, 2014/2015
Procura na Lista
50 IAED, 2014/2015
Remoção da Lista
t = prev->next;
prev->next = t->next;
prev
51 IAED, 2014/2015
Remoção da Lista com Procura
prev
52 IAED, 2014/2015
Remoção da Lista com Procura
link delete(link head, char* text)
{
link t, prev;
for(t = head, prev = NULL; t != NULL;
prev = t, t = t->next) {
if(strcmp(t->text, text) == 0) {
if(t == head)
head = ?t->next;
else
prev->next = t->next;
free(t->text);
free(t);
}
}
return head;
}
53 IAED, 2014/2015
Remoção da Lista com Procura
link delete(link head, char* text)
{
link t, prev;
for(t = head, prev = NULL; t != NULL;
prev = t, t = t->next) {
if(strcmp(t->text, text) == 0) {
if(t == head)
head = t->next;
else
prev->next = t->next;
free(t->text);
free(t);
}
}
return head;
}
54 IAED, 2014/2015
Remoção da Lista com Procura
link delete(link head, char* text)
{
link t, prev;
for(t = head, prev = NULL; t != NULL;
prev = t, t = t->next) {
if(strcmp(t->text, text) == 0) {
if(t == head)
head = t->next;
else
prev->next = t->next;
FREEnode(t);
} void FREEnode(link t)
} {
return head; free(t->text);
} free(t);
}
55 IAED, 2014/2015
Inserção no Início – Sem Valor de Retorno
56 IAED, 2014/2015
Próxima aula: Tipos Abstractos de Dados
• Motivação
• Objectos
• Pilhas
• Exemplos de clientes
• ADTs para FIFOs e filas
57 IAED, 2014/2015
ADTs (Abstract Data Types): Motivação
Listas Inteiros
Pilhas Reais
Amontoado Strings
FIFOs Estruturas
• O procedimento para inserir um inteiro, real, uma string ou
uma estrutura numa lista é similar
• O código pode (e deve) ser re-utilizado
• Abstracção dos detalhes de implementação
1 IAED, 2014/2015
ADT e Colecções de Objectos
• Operações típicas
– Comparações entre objectos
– Operações de entrada e saída (leitura e escrita)
– Inserção em colecções
– Apagamento de colecções
– Alteração de propriedades (e.g., prioridade)
2 IAED, 2014/2015
Vantagens do Uso de ADTs
• Solução elegante
• Separa os problemas:
– Alto nível: interface de operações sobre tipo de dados
– Baixo nível: como manter as estruturas de dados
• Permite comparar diferentes implementações
• Permite re-utilizar o código
3 IAED, 2014/2015
Regras de Scope
IAED, 2014/2015
Organização de Programas
calculadora.c
estatistica.c
trigonom.c
aritmetica.c
5 IAED, 2014/2015
Regras de Scope
6 IAED, 2014/2015
Block scope
7 IAED, 2014/2015
Block scope
int acumulador;
10 IAED, 2014/2015
File scope: “variáveis globais estáticas”
11 IAED, 2014/2015
Program scope: “variáveis externas”
IAED, 2014/2015
De uma forma geral, temos que…
IAED, 2014/2015
Header Files (Ficheiros de Cabeçalho)
calculadora.c
estatistica.c
trigonom.c
aritmetica.c
calculadora.h
15 IAED, 2014/2015
Exemplo 1: “variáveis externas”
• Variáveis externas
– utilizadas antes de serem definidas, ou definidas noutro ficheiro,
deverão ser declaradas com a palavra-chave extern
stuff.h stuff.c
main.c
16 IAED, 2014/2015
Exemplo 1: “variáveis externas”
• Variáveis externas
– utilizadas antes de serem definidas, ou definidas noutro ficheiro,
deverão ser declaradas com a palavra-chave extern
Aqui não estou a
reservar memória.
#include “stuff.h” #ifndef _STUFF_
#define _STUFF_
int x;
#include <stdio.h>
#include “stuff.h”
int main()
{ void print();
void print()
x=2; {
print(); extern int x;
printf(“%d\n”,x);
return 0; #endif }
}
stuff.h stuff.c
main.c
Aqui estou a definir x e
a reservar memoria
17
para um inteiro IAED, 2014/2015
Exemplo 2: Módulo para números complexos
• complexos.h
Garante que este
ficheiro é apenas
incluído uma vez.
#ifndef COMPLEXOS_H
#define COMPLEXOS_H
typedef struct {
float real, img;
} complexo;
#endif
IAED, 2014/2015
Exemplo 2: Módulo para números complexos
• complexos.c #include <stdio.h>
#include "complexos.h"
int main()
{
complexo x, y, z;
x = le_complexo();
y = le_complexo();
z = soma(x, y);
escreve_complexo(x);
printf(" + ");
escreve_complexo(y);
printf(" = ");
escreve_complexo(z);
printf("\n");
return 0;
Compilação!
}
IAED, 2014/2015
Operações sobre ficheiros
fp=fopen(”tests.txt", "r");
24 IAED, 2014/2015
Operações sobre ficheiros
25 IAED, 2014/2015
Exemplo
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp; Se não conseguir
abrir fp fica igual a
fp = fopen("teste.txt", "r"); NULL
if (fp == NULL) {
printf(“teste.txt: No such file or directory\n”);
exit(1);
}
return 0;
}
26 IAED, 2014/2015
Exemplo
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
fp = fopen("teste.txt", "r");
if (fp == NULL) {
perror(“teste.txt”); Escreve a mesma
exit(1); mensagem de erro.
}
return 0;
}
27 IAED, 2014/2015
Exemplo 2
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
fp = fopen("teste.txt", "r");
if (fp == NULL) {
perror(“teste.txt”);
exit(1); Fecha o ficheiro
}
fclose(fp);
return 0;
}
28 IAED, 2014/2015
Exemplo 3
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
fp = fopen("teste.txt", ”w");
if (fp == NULL) {
perror(“teste.txt”); Escreve para um
exit(1); ficheiro
}
fclose(fp);
int main()
{
FILE *fp;
fp = fopen("teste.txt", ”w");
if (fp == NULL) {
perror(“teste.txt”); Escreve para um
exit(1); ficheiro
} (alternativa)
fclose(fp);
int main()
{
FILE *myfile; int i;
float mydata[100];
myfile = fopen(”info.dat", ”r");
Lê um conjunto
if (myfile== NULL) {
de 100 floats
perror(“info.dat”);
guardados num
exit(1);
}
ficheiro
for (i=0;i<100;i++)
fscanf(myfile,”%f”,&mydata[i]);
fclose(myfile);
return 0;
} IAED, 2014/2015
31
32 IAED, 2014/2015
Tipos Abstractos de Dados
Sedgewick: Capítulo 4
IAED, 2014/2015
Outro exemplo: filas de espera (FIFO)
Interface do ADT Queue
QUEUE.h
void QUEUEinit(int);
int QUEUEempty();
void QUEUEput(Item);
Item QUEUEget();
20 IAED, 2014/2015
Implementação do ADT FIFO (Listas)
QUEUE.c
#include <stdlib.h>
#include "Item.h"
#include "QUEUE.h"
struct QUEUEnode {
Item item;
link next;
};
21 IAED, 2014/2015
Implementação do ADT FIFO (Listas)
QUEUE.c
void QUEUEinit(int maxN) {
head = NULL;
Inicio a head e a tail a
tail = NULL; NULL
}
int QUEUEempty() {
return head == NULL;
}
x->item = item;
x->next = next;
return x;
}
22 IAED, 2014/2015
Implementação do ADT FIFO (Listas)
QUEUE.c (cont)
void QUEUEput(Item item) { Quando a fila está
if (head == NULL) { vazia...
head = (tail = NEW(item, head));
return;
Nos outros casos,
}
insiro no fim.
tail->next = NEW(item, tail->next);
tail = tail->next;
}
Actualizo a tail.
Item QUEUEget() {
Item item = head->item; Guardo o conteudo do
link t = head->next; primeiro elemento numa
variavel auxiliar.
free(head);
head = t;
return item; Liberto a memória e
retorno o elemento
}
removido
23 IAED, 2014/2015
Implementação do ADT FIFO (Tabelas)
QUEUE.c
#include <stdlib.h>
0
#include "Item.h " N
#include "QUEUE.h"
Circular buffer
static Item *q;
static int N, head, tail;
24 IAED, 2014/2015
Implementação do ADT FIFO (Tabelas)
QUEUE.c (cont)
int QUEUEempty() {
return head % N == tail; 0
} N
Item QUEUEget() {
head = head % N;
return q[head++];
}
25 IAED, 2014/2015
ADTs de 1a Ordem
26 IAED, 2014/2015
ADTs de 1a Ordem
• Solução: em vez da informação da estrutura de dados
ser guardada em variáveis globais, é guardada numa
estrutura que é passada como argumento a cada função
QUEUE.h
typedef struct queue *Q;
typedef struct QUEUEnode *link;
struct QUEUEnode { Item item; link next; };
struct queue { link head; link tail; };
QUEUE.h (original)
typedef struct QUEUEnode* link;
Q QUEUEinit(int maxN); QUEUE.h (original)
#include "Item.h"
#include "QUEUE.h"
x->item = item;
QUEUE.c (original)
x->next = next;
link NEW(Item item, link next) {
return x; link x = (link) malloc(sizeof(struct QUEUEnode));
}
x->item = item;
x->next = next;
return x;
28 } IAED, 2014/2015
Implementação do ADT FIFO de 1a Ordem
QUEUE.c (cont)
Q QUEUEinit(int maxN) {
Q q = (Q)malloc(sizeof(struct queue));
q->head = NULL;
q->tail = NULL;
return q;
}
int QUEUEempty(Q q) {
return q->head == NULL;
}
QUEUE.c (original)
void QUEUEinit(int maxN) {
head = NULL;
tail = NULL;
}
int QUEUEempty() {
return head == NULL;
29 } IAED, 2014/2015
Implementação do ADT FIFO de 1a Ordem
QUEUE.c (cont)
Item QUEUEget(Q q) {
Item item = q->head->item;
link t = q->head->next;
free(q->head);
q->head = t;
return item;
}
QUEUE.c (original)
Item QUEUEget() {
Item item = head->item;
link t = head->next;
free(head);
head = t;
return item;
31 } IAED, 2014/2015
Implementação do ADT FIFO de 1a Ordem
QUEUE.c (cont)
Item QUEUEget(Q q) {
Item item = q->head->item;
link t = q->head->next;
free(q->head);
q->head = t;
return item; /* esta função retorna o item de forma a que a sua
informação seja processada (se for o caso) e, se necessário, a
sua memoria é libertada posteriormente */
}
32 IAED, 2014/2015
Cliente do ADT FIFO de 1a Ordem
#include <stdio.h>
#include <stdlib.h>
#include "Item.h"
#include "QUEUE.h"
#define M 10
33 IAED, 2014/2015
Conseguem imaginar uma forma alternativa
de implementar uma queue FIFO?
head
prev next
NULL
NULL
34 IAED, 2014/2015
Conseguem imaginar uma forma alternativa
de implementar uma queue FIFO?
35 IAED, 2014/2015
Tabelas de Dispersão
Sedgewick: Capítulo 14
IAED, 2014/2015
Tabelas de Dispersão (Hash Tables)
• Funções de dispersão
• Encadeamento externo
• Procura linear
• Double hashing (dispersão dupla)
• Eficiência da procura
37 IAED, 2014/2015
Tabelas de Dispersão - Motivação
– Vector
– Lista
38 IAED, 2014/2015
Tabelas de Dispersão
• Guardar
função de
dispersão índice
• Procurar
transforma
uma chave
num índice
39 IAED, 2014/2015
Função de Dispersão (Hashing)
40 IAED, 2014/2015
Função de Dispersão
41 IAED, 2014/2015
Função de Dispersão – Números
• hash(k ) = k mod M
43 IAED, 2014/2015
Função de Dispersão – Strings
44 IAED, 2014/2015
Função de Dispersão – Strings v2.0
45 IAED, 2014/2015
Colisões
• Guardar / Procurar
colisão !
função de
dispersão
46 IAED, 2014/2015
Resolução por Encadeamento Externo
0 707
1
2 72
3 Ordem de inserção
4 707, 72, 14, 70, 76, 20
5
6
hash(k ) = k mod 7
47 IAED, 2014/2015
Resolução por Encadeamento Externo
0 14 707
1
2 72
3 Ordem de inserção
4 707, 72, 14, 70, 76, 20
5
6
hash(k ) = k mod 7
48 IAED, 2014/2015
Resolução por Encadeamento Externo
0 70 14 707
1
2 72
3 Ordem de inserção
4 707, 72, 14, 70, 76, 20
5
6
hash(k ) = k mod 7
49 IAED, 2014/2015
Resolução por Encadeamento Externo
0 70 14 707
1
2 72
3 Ordem de inserção
4 707, 72, 14, 70, 76, 20
5
6 76 hash(k ) = k mod 7
50 IAED, 2014/2015
Resolução por Encadeamento Externo
0 70 14 707
1
2 72
3 Ordem de inserção
4 707, 72, 14, 70, 76, 20
5
6 20 76 hash(k ) = k mod 7
51 IAED, 2014/2015
Resolução por Encadeamento Externo
static link *heads;
static int M;
void STinit(int max) {
int i;
M = max;
heads = (link*)malloc(M*sizeof(link));
for (i = 0; i < M; i++) heads[i] = NULL;
}
void STinsert(Item item) {
int i = hash(key(item), M);
heads[i] = insertBeginList(heads[i], item);
}
void STdelete(Item item) {
int i = hash(key(item), M);
heads[i] = removeItemList(heads[i], item);
}
Item STsearch(Key v) {
int i = hash(v, M);
return searchList(heads[i], v);
}
52 IAED, 2014/2015
Resolução por Encadeamento Externo
53 IAED, 2014/2015
Exercício
54 IAED, 2014/2015
Exercício V={13, 11, 10, 2, 22, 35, 45, 1, 143, 333, 6, 99998}
0 10
1 11
2 2
3 13
4
5
6
7
8
9
55 IAED, 2014/2015
Exercício V={13, 11, 10, 2, 22, 35, 45, 1, 143, 333, 6, 99998}
0 10
1 11
2 22 2
3 13
4
5 35
6
7
8
9
56 IAED, 2014/2015
Exercício V={13, 11, 10, 2, 22, 35, 45, 1, 143, 333, 6, 99998}
0 10
1 11
2 22 2
3 13
4
5 45 35
6
7
8
9
57 IAED, 2014/2015
Exercício V={13, 11, 10, 2, 22, 35, 45, 1, 143, 333, 6, 99998}
0 10
1 1 11
2 22 2
3 13
4
5 45 35
6
7
8
9
58 IAED, 2014/2015
Exercício V={13, 11, 10, 2, 22, 35, 45, 1, 143, 333, 6, 99998}
0 10
1 1 11
2 22 2
3 333 143 13
4 Resposta:
Posição 3: 333, 143, 13
5 45 35
Colisões: 5
6 6
7
8 99998
9
59 IAED, 2014/2015
Resolução por Procura Linear
0 707 14 !!
1
2 72
Ordem de inserção
3
707, 72, 14, 70, 76, 20
4
5
6
hash(k ) = k mod 7
61 IAED, 2014/2015
Resolução por Procura Linear
0 707
1 14
2 72
Ordem de inserção
3
707, 72, 14, 70, 76, 20
4
5
6
hash(k ) = k mod 7
62 IAED, 2014/2015
Resolução por Procura Linear
0 707 70 !!
1 14
2 72
Ordem de inserção
3
707, 72, 14, 70, 76, 20
4
5
6
hash(k ) = k mod 7
63 IAED, 2014/2015
Resolução por Procura Linear
0 707
1 14
2 72
Ordem de inserção
3 70
707, 72, 14, 70, 76, 20
4
5
6 76
hash(k ) = k mod 7
64 IAED, 2014/2015
Resolução por Procura Linear
0 707
1 14
2 72
Ordem de inserção
3 70
707, 72, 14, 70, 76, 20
4
5
20 6 76
hash(k ) = k mod 7
65 IAED, 2014/2015
Resolução por Procura Linear
0 707
1 14
2 72
Ordem de inserção
3 70
707, 72, 14, 70, 76, 20
4 20
5
6 76
hash(k ) = k mod 7
66 IAED, 2014/2015
Resolução por Procura Linear: Init & Insert
#include <stdlib.h>
#include "Item.h"
#define null(A) (key(st[A]) == key(NULLitem))
static int N, M;
static Item *st;
void STinit(int max) {
int i;
N = 0;
M = 2*max;
st = (Item*)malloc(M*sizeof(Item));
for (i = 0; i < M; i++)
st[i] = NULLitem;
}
void STinsert(Item item) {
Key v = key(item);
int i = hash(v, M);
while (!null(i)) i = (i+1) % M;
st[i] = item;
N++;
}
67 IAED, 2014/2015
Resolução por Procura Linear: search
68 IAED, 2014/2015
Remoção de Items em Procura Linear
69 IAED, 2014/2015
Remoção de Items em Procura Linear
72 IAED, 2014/2015
Resolução por Procura Linear
73 IAED, 2014/2015
Exercício
74 IAED, 2014/2015
Exercício V={13, 11, 10, 2, 22, 34, 45, 1}
0 10
1 11
2 2
3 13
4 22
5 34
6 45
7 1
8
9
75 IAED, 2014/2015
Exercício
76 IAED, 2014/2015
Exercício V={13, 11, 10, 2, 22, 34, 45, 1}
0 10
1 11
2 2
3 13
4 22
5 34
6 45
7 1
8
9
77 IAED, 2014/2015
Exercício V={13, 11, 10, 2, 22, 34, 45, 1}
0 10
1 11
2 2
3 13
4
5 34
6 45
7 1
8
9
78 IAED, 2014/2015
Exercício V={13, 11, 10, 2, 22, 34, 45, 1}
0 10
1 11
2 2
3 13
4 34
5 45
6 1
7
8
9
79 IAED, 2014/2015
Resolução por Double Hashing
80 IAED, 2014/2015
Resolução por Double Hashing
Item STsearch(Key v) {
Item STsearch(Key v) {
int i = hash(v, M);
int i = hash(v, M); while (!null(i))
int k = hashtwo(v, M); if (eq(v, key(st[i]))
while (!null(i)) return st[i];
if eq(v, key(st[i])) else
return st[i]; i = (i+1) % M;
return NULLitem;
else i = (i+k) % M;
}
return NULLitem;
}
81 IAED, 2014/2015
Resolução por Double Hashing
82 IAED, 2014/2015
Hash Tables: Exercício (Double Hashing)
Considere uma tabela de dispersão de dimensão M=7 com
resolução por double hashing e funções de dispersão:
H1(k)=k mod M
H2(k)=1+3k
Qual o conteúdo da tabela depois de inserirmos (por esta ordem)
os seguintes valores
9, 7, 8, 1, 3, 0
0: 7 0
1: 8 1
2: 9
3: 3
4:
5:
83 6: IAED, 2014/2015
Hash Tables: Exercício (Double Hashing)
Considere uma tabela de dispersão de dimensão M=7 com
resolução por double hashing e funções de dispersão:
h1(h)=k mod M
h2(h)=1+3k
Qual o conteúdo da tabela depois de inserirmos (por esta ordem)
os seguintes valores
9, 7, 8, 1, 3, 0
0: 7
1: 8
2: 9
3: 3
4: 0
5: 1
84 6: IAED, 2014/2015
Tabelas de Dispersão Dinâmicas
85 IAED, 2014/2015
Solução Dinâmica para Procura Linear
void expand();
void STinsert(Item item) {
Key v = key(item);
int i = hash(v, M);
while (!null(i))
i = (i+1) % M;
st[i] = item;
if (N++ > M/2)
expand();
} Aloca Memória;
void expand() { Cria um novo st;
int i; Duplica o M
Item *t = st;
init(M+M);
for (i = 0; i < M/2; i++)
if (key(t[i]) != key(NULLitem))
STinsert(t[i]);
free(t);
}
86 IAED, 2014/2015
Tabelas de Dispersão - Conclusão
• Vantagens
– Concretizam operações de inserção e procura em tempo
constante (caso médio)
• procura linear - a mais rápida (tabela esparsa)
• dispersão dupla - melhor compromisso tempo/memória
• encadeamento externo - mais fácil de concretizar, maior carga mas
pior uso de memória
• Inconvenientes
– Não há garantia de desempenho
– Custo de função de dispersão alto se chaves longas
– Ocupam mais memória do que necessário
– Não suportam eficientemente as operações de ordenação e
selecção
87 IAED, 2014/2015
Tabelas de Dispersão
Sedgewick: Capítulo 14
IAED, 2014/2015
Resolução por Double Hashing
76 IAED, 2014/2015
Resolução por Double Hashing
Item STsearch(Key v) {
Item STsearch(Key v) {
int i = hash(v, M);
int i = hash(v, M); while (!null(i))
int k = hashtwo(v, M); if (eq(v, key(st[i]))
while (!null(i)) return st[i];
if eq(v, key(st[i])) else
return st[i]; i = (i+1) % M;
return NULLitem;
else i = (i+k) % M;
}
return NULLitem;
}
77 IAED, 2014/2015
Hash Tables: Exercício (Double Hashing)
Considere uma tabela de dispersão de dimensão M=7 com
resolução por double hashing e funções de dispersão:
H1(k)=k mod M
H2(k)=1+3k
Qual o conteúdo da tabela depois de inserirmos (por esta ordem)
os seguintes valores
9, 7, 8, 1, 3, 0
0: 7 0
1: 8 1
2: 9
3: 3
4:
5:
79 6: IAED, 2014/2015
Hash Tables: Exercício (Double Hashing)
Considere uma tabela de dispersão de dimensão M=7 com
resolução por double hashing e funções de dispersão:
h1(h)=k mod M
h2(h)=1+3k
Qual o conteúdo da tabela depois de inserirmos (por esta ordem)
os seguintes valores
9, 7, 8, 1, 3, 0
0: 7
1: 8
2: 9
3: 3
4: 0
5: 1
80 6: IAED, 2014/2015
Tabelas de Dispersão Dinâmicas
81 IAED, 2014/2015
Solução Dinâmica para Procura Linear
void expand();
void STinsert(Item item) {
Key v = key(item);
int i = hash(v, M);
while (!null(i))
i = (i+1) % M;
st[i] = item;
if (N++ > M/2)
expand();
} Aloca Memória;
void expand() { Cria um novo st;
int i; Duplica o M
Item *t = st;
init(M+M);
for (i = 0; i < M/2; i++)
if (key(t[i]) != key(NULLitem))
STinsert(t[i]);
free(t);
}
82 IAED, 2014/2015
Tabelas de Dispersão - Conclusão
• Vantagens
– Concretizam operações de inserção e procura em tempo
constante (caso médio)
• procura linear - a mais rápida (tabela esparsa)
• dispersão dupla - melhor compromisso tempo/memória
• encadeamento externo - mais fácil de concretizar, maior carga mas
pior uso de memória
• Inconvenientes
– Não há garantia de desempenho
– Custo de função de dispersão alto se chaves longas
– Ocupam mais memória do que necessário
– Não suportam eficientemente as operações de ordenação e
selecção
83 IAED, 2014/2015
Árvores AVL
IAED, 2014/2015
Resumo da aula de hoje
• Exercícios
2 IAED, 2014/2015
Estrutura de uma Árvore Binária
#include "Item.h"
3 IAED, 2014/2015
Árvores de Procura Binárias (BST)
12 32
8 18 23 45
2 9
4 IAED, 2014/2015
Árvores de Procura Binárias (BST)
• Vamos procurar o 2
• No pior caso, a pesquisa escala com a profundidade da
árvore.
20
12 32
8 18 23 45
2 9
5 IAED, 2014/2015
Inserção de um novo elemento
20
12 32
8 18 23 45
2 9
6 IAED, 2014/2015
Remoção de um elemento
• Mais difícil: 3 possibilidades.
20
1. 5 2.
22
7
45
3.
IAED, 2014/2015
Exemplos: Remoção de um elemento
12 IAED, 2014/2015
Travessia em Pre-Order
void traverse(link h)
20
{
if (h == NULL) 12 32
return;
visit(h->item);
traverse(h->l); 8 18 23 45
traverse(h->r);
} 2 9
13 IAED, 2014/2015
Travessia em In-Order (sorted!!)
14 IAED, 2014/2015
Travessia em Post-Order
15 IAED, 2014/2015
Pesquisas em BST
16 IAED, 2014/2015
Árvores Binárias Equilibradas
1 0 0 0
8 18 23 45
0 0
2 9
3
20
2 1
12 32
1 0 0 0
8 18 23 45
0 0
2 9
19 IAED, 2014/2015
Inserção em Árvores AVL
3
20
2 1
12 32
1 0 0 0
8 18 23 45
0 0
2 9
21 IAED, 2014/2015
Inserção em Árvores AVL
1 0 0 0
8 18 23 45
0 0
2 9
22 IAED, 2014/2015
Inserção em Árvores AVL
4
20
Height
3 1
12 32
2 0 0 0
8 18 23 45
1 0
2 9
0
1
23 IAED, 2014/2015
Inserção em Árvores AVL
4
20
Height
árvore 3 1
desequilibrada ! 12 32
2 0 0 0
8 18 23 45
1 0
2 9
0
1
24 IAED, 2014/2015
Inserção em Árvores AVL
4
20
Height
árvore 3 1
desequilibrada ! 12 32
2 0 0 0
8 18 23 45
1 0
2 9
0
1
25 IAED, 2014/2015
20
8 18 23 45
2 9
1
3
20 Height
árvore 2
1
equilibrada ! 8 32
1 1 0 0
2 12 23 45
0 0 0
1 9 18
26 IAED, 2014/2015
Inserção em Árvores AVL
1 1 0 0
2 12 23 45
0 0 0
1 9 18
27 IAED, 2014/2015
Inserção em Árvores AVL
1 0 0 0
2 12 23 45
0 0 0
1 9 18
28 IAED, 2014/2015
Operações de Rotação - Esquerda
link rotL(link h) {
link x = h->r;
h->r = x->l;
x->l = h;
return x;
}
x
H
h h
F F
x I
D H D
G
B E G I B E
A C A C
29 IAED, 2014/2015
Operações de Rotação - Direita
link rotR(link h) {
link x = h->l;
h->l = x->r;
x->r = h;
return x;
}
D D x
h
B H B F
x h
A C F I A C E H
E G G I
30 IAED, 2014/2015
Inserção em Árvores AVL
31 IAED, 2014/2015
Equilibragem de Árvores AVL
A B
B A C
C
rotação
esquerda
32 IAED, 2014/2015
Equilibragem de Árvores AVL
C B
B A C
A
rotação
direita
33 IAED, 2014/2015
AVL Ex. 1: Inserção com rotações simples
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos inserir o elemento 18
0
45
Balance factor
0 0
36 63
0 0 0 0
27 39 54 72
34 IAED, 2014/2015
AVL Ex. 1: Inserção com rotações simples
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos inserir o elemento 18
• Esta BST está equilibrada?
1
45
Balance factor
1 0
36 63
1 0 0 0
27 39 54 72
0
18
35 IAED, 2014/2015
AVL Ex. 1: Inserção com rotações simples
• Agora vamos introduzir o elemento 9... Está equilibrada?
• NÃO!!!!
• Vamos subir do 9 em direção à raiz até encontrar um elemento
desequilibrado. 2
45
Balance factor
2 0
36 63
2 0 0 0
27 39 54 72
1
18
0
36
9 IAED, 2014/2015
AVL Ex. 1: Inserção com rotações simples
• Para equilibrar, basta fazer uma rotação simples para a direita
(rotR) aplicada ao elemento 27
2
45
2 0
36 63
2 0 0 0
27 39 54 72
1
18
0
37
9 IAED, 2014/2015
AVL Ex. 1: Inserção com rotações simples
• Para equilibrar, basta fazer uma rotação simples para a direita
(rotR) aplicada ao elemento 27
• ...e já está!!!
1
45
1 0
36 63
0 0 0 0
18 39 54 72
0 0
9 27
IAED, 2014/2015
AVL Ex. 1: Inserção com rotações simples
2
45
2 0
36 63
2 0 0 0
27 39 54 72
1
18 RECEITA 1: Quando o novo nó é inserido
na sub-árvore da esquerda, da sub-
0
árvore da esquerda do elemento
9 desequilibrado, basta-nos aplicar uma
IAED, 2014/2015
39
rotR a esse elemento.
AVL Ex. 2: Inserção com rotações simples
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos inserir o elemento 91
-1
45
0 -1
36 63
0 0 0 -1
27 39 54 72
0
89
40 IAED, 2014/2015
AVL Ex. 2: Inserção com rotações simples
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos inserir o elemento 91
-2
45
0 -2
36 63
0 0 0 -2
27 39 54 72
-1
89
41 IAED, 2014/2015
91
AVL Ex. 2: Inserção com rotações simples
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos inserir o elemento 91
-2
45
0 -2
36 63
0 0 0 -2
27 39 54 72
-1
• RESULTADO FINAL:
-1
45
0 -1
36 63
0 0 0 0
27 39 54 89
0
0
72 91
43 IAED, 2014/2015
AVL Ex. 3: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos inserir o elemento 56
-1
45
0 1
36 63
0
50
44 IAED, 2014/2015
AVL Ex. 3: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos inserir o elemento 56
Receita 3: O novo nó é -2
inserido na sub-árvore 45
da direita, da sub-árvore 0 2
da esquerda do elemento 36 63
desequilibrado!!
O que fazer ? Rotação -1
dupla Esquerda-Direita 50
0
56
45 IAED, 2014/2015
Equilibragem de Árvores AVL
C C
A B
B A
rotação
esquerda
46 IAED, 2014/2015
Equilibragem de Árvores AVL
C B
A A C
B
rotação
esquerda, direita
47 IAED, 2014/2015
Equilibragem de Árvores AVL
A A
C B
B C
rotação
direita
48 IAED, 2014/2015
Equilibragem de Árvores AVL
A B
C A C
B
rotação
direita, esquerda
49 IAED, 2014/2015
AVL Ex. 3: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos inserir o elemento 56
Receita 3: O novo nó é -2
inserido na sub-árvore 45
da direita, da sub-árvore 0 2
da esquerda do elemento 36 63
desequilibrado!!
O que fazer ? Rotação -1
dupla Esquerda-Direita 50 rotL
0
56
50 IAED, 2014/2015
AVL Ex. 3: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos inserir o elemento 56
Receita 3: O novo nó é -2
inserido na sub-árvore 45
da direita, da sub-árvore 0 2
da esquerda do elemento 36 63
desequilibrado!!
O que fazer ? Rotação 1
dupla Esquerda-Direita 56 rotL
0
50
51 IAED, 2014/2015
AVL Ex. 3: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos inserir o elemento 56
Receita 3: O novo nó é -2
inserido na sub-árvore 45
da direita, da sub-árvore 0 2
da esquerda do elemento 36 63 rotR
desequilibrado!!
O que fazer ? Rotação 1
dupla Esquerda-Direita 56
0
50
52 IAED, 2014/2015
AVL Ex. 3: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos inserir o elemento 56
Receita 3: O novo nó é -1
inserido na sub-árvore 45
da direita, da sub-árvore 0 0
da esquerda do elemento 36 56 rotR
desequilibrado!!
O que fazer ? Rotação 0 0
dupla Esquerda-Direita 50 63
53 IAED, 2014/2015
AVL Ex. 3: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos inserir o elemento 56
-1
• RESULTADO FINAL: 45
0 0
36 56
0 0
50 63
54 IAED, 2014/2015
AVL Ex. 4: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Depois de inserir o elemento 65 temos:
-1
45
0 1
36 63
0
70
55 IAED, 2014/2015
AVL Ex. 4: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Depois de inserir o elemento 65 temos:
-2
45
0 -2
36 63
1
Receita 4: O novo nó é 70 rotR
inserido na sub-árvore da
esquerda, da sub-árvore da 0
direita do elemento 65
desequilibrado!!
O que fazer ? Rotação dupla
Direita-Esquerda IAED, 2014/2015
56
AVL Ex. 4: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Depois de inserir o elemento 65 temos:
-2
45
0 -2
36 63
-1
Receita 4: O novo nó é 65 rotR
inserido na sub-árvore da
esquerda, da sub-árvore da
direita do elemento 70
desequilibrado!!
O que fazer ? Rotação dupla
Direita-Esquerda IAED, 2014/2015
57
AVL Ex. 4: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Depois de inserir o elemento 65 temos:
-2
45
0 -2
36 63 rotL
-1
Receita 4: O novo nó é 65
inserido na sub-árvore da
esquerda, da sub-árvore da
direita do elemento 70
desequilibrado!!
O que fazer ? Rotação dupla
Direita-Esquerda IAED, 2014/2015
58
AVL Ex. 4: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Depois de inserir o elemento 65 temos :
-1
45
0 0
36 65 rotL
0
0
Receita 4: O novo nó é 63 70
inserido na sub-árvore da
esquerda, da sub-árvore da
direita do elemento
desequilibrado!!
O que fazer ? Rotação dupla
Direita-Esquerda IAED, 2014/2015
59
AVL Ex. 4: Inserção com rotações duplas
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Depois de inserir o elemento 65 temos (resultado final):
-1
45
0 0
36 65
0
0
63 70
60 IAED, 2014/2015
Resumo
61 IAED, 2014/2015
Remoção em Árvores AVL
1
20
Balance factor
1 -1
12 32
0 0 0
8 18 45
0 0
2 9
62 IAED, 2014/2015
Remoção em Árvores AVL
2
árvore 20
desequilibrada !
1 0
12 32
0 0
8 18
0 0
2 9
63 IAED, 2014/2015
Remoção em Árvores AVL
64 IAED, 2014/2015
AVL Ex. 5: Remoção de nós
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos remover o elemento 72:
1
45
0 -1
36 63
1 -1 0
27 39 72
0
0
18 40
65 IAED, 2014/2015
AVL Ex. 5: Remoção de nós
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos remover o elemento 72:
2
45 rotR
0 0
36 63
1 -1
27 39
0
0
18 40
66 IAED, 2014/2015
AVL Ex. 5: Remoção de nós
• Considere a árvore em baixo. Os números ao lado correspondem
ao balance factor = height (left) – height (right)
• Vamos remover o elemento 72:
-1
36
1 1
27 45
1 0
0
18 39 63
0
40
67 IAED, 2014/2015
Pesquisa em Árvores AVL
68 IAED, 2014/2015
Desempenho de Árvores AVL
• Pesquisa: O (log N)
– Profundidade é O(log N ) , não é necessário equilibrar
• Inserção: O (log N)
– Procurar a posição para inserir é O (log N)
– Manter equilibrada é O (log N) : subir na árvore e equilibrar 1 vez
• Remoção: O (log N)
– Procurar o elemento a remover é O (log N)
– Manter equilibrada é O (log N) : subir na árvore e equilibrar no
máximo O (log N) vezes
69 IAED, 2014/2015
Exercício 1
70 IAED, 2014/2015
Exercício 1
63, 9, 19, 27, 18, 108, 99 e 81
63 19
9 63
9 RotL(9) + RotR(63)
à
18 27 108 <-RotR
19
99
81
71 IAED, 2014/2015
Exercício 1
Balance factors
-1
19
-1 -1
9 63
0 0 0
18 27 99
0 0
81 108
72 IAED, 2014/2015
Exercício 2
Balance factors
-1
19
-1 -1
9 63
0 0 0
18 27 99
0 0
81 108
73 IAED, 2014/2015
Exercício 2
nó desequilibrado!
-2
19
0 -1
9 63
0 0
27 99
0 0
81 108
74 IAED, 2014/2015
Exercício 2
nó desequilibrado!
-2
19
0 -1
9 63
0 0
27 99
0 0
81 108
O que fazer?
75 IAED, 2014/2015
Exercício 2
nó desequilibrado!
-2
19
0 -1
9 63
0 0
27 99
0 0
81 108
O que fazer?
Rodar o elemento desequilibrado para a esquerda...
76 IAED, 2014/2015
Exercício 2
0
63
0 0
19 99
0 0
9 27 81 108
Já está!
77 IAED, 2014/2015
ADTs + AVLs: Alterações ao código anterior
ST.h
#ifndef _ST_
#define _ST_
#include <stdlib.h>
#include <stdio.h>
#include "Item.h"
void STinit(link*);
int STcount(link);
Item STsearch(link,Key);
void STinsert(link*,Item);
void STdelete(link*,Key);
void STsort(link,void (*visit)(Item));
void
78 STfree(link*);
#endif
IAED, 2014/2015
Height vai guardando
ST.c (alterações a verde) a altura do nó
#include "ST.h”
height_left = height(h->l);
height_right = height(h->r);
h->height =
height_left > height_right ? height_left + 1 : height_right + 1;
height_left = height(x->l);
height_right = height(x->r);
x->height =
height_left > height_right ? height_left + 1 : height_right + 1;
return x;
80
}
IAED, 2014/2015
ST.c (alterações a verde)
link rotR(link h)
{
Actualizar a altura
int height_left, height_right; dos nós
link x = h->l; envolvidos
h->l = x->r;
x->r = h;
height_left = height(h->l);
height_right = height(h->r);
h->height =
height_left > height_right ? height_left + 1 : height_right + 1;
height_left = height(x->l);
height_right = height(x->r);
x->height =
height_left > height_right ? height_left + 1 : height_right + 1;
return x;
81
}
IAED, 2014/2015
ST.c (alterações a verde)
IAED, 2014/2015
ST.c (alterações a verde)
link AVLbalance(link h) {
int balanceFactor;
if (h==NULL) return h;
balanceFactor= Balance(h);
if(balanceFactor>1) {
if (Balance(h->l)>0) h=rotR(h);
else h=rotLR(h);
}
else if(balanceFactor<-1){
if (Balance(h->r)<0) h = rotL(h);
else h = rotRL(h);
}
else{
int height_left = height(h->l);
int height_right = height(h->r);
h->height =
height_left > height_right ? height_left + 1 : height_right + 1;
83
}
return h;
} IAED, 2014/2015
ST.c (alterações a verde)
84
IAED, 2014/2015
ST.c (alterações a verde)
link deleteR(link h, Key k) {
if (h == NULL) return h;
else if (less(k, key(h->item))) h->l = deleteR(h->l,k);
else if (less(key(h->item), k)) h->r = deleteR(h->r,k) ;
else{
if (h->l !=NULL && h->r !=NULL){
link aux = max(h->l);
{Item x; x = h->item; h->item = aux->item; aux->item = x;}
h->l = deleteR(h->l, key(aux->item));
}
else {
link aux = h;
if (h->l == NULL && h->r == NULL) h=NULL;
else if (h->l == NULL) h = h->r;
else h = h->l;
deleteItem(aux->item);
free(aux);
}
85
}
h = AVLbalance(h);
return h; IAED, 2014/2015
}
Árvores Binárias (1st round)
IAED, 2014/2015
Árvores Binárias
2 IAED, 2014/2015
Estrutura de uma Árvore Binária
#include "Item.h"
3 IAED, 2014/2015
Estrutura de uma Árvore Binária
#include "Item.h"
4 IAED, 2014/2015
Árvores de Procura Binárias (BST)
12 32
8 18 23 45
2 9
5 IAED, 2014/2015
Basics...
#include <stdlib.h>
#include "Item.h"
void init() {
head = NULL;
}
6 IAED, 2014/2015
Pesquisa de um item v: Função search
12 32
8 18 23 45
2 9 IAED, 2014/2015
7
Pesquisa de um item v: Função search
link search(link h, Item v) {
if (h == NULL)
return NULL;
if (eq(v, h->item))
return h;
if (less(v, h->item))
return search(h->l, v);
else
20
return search(h->r, v);
}
12 32
8 18 23 45
2 9
8 IAED, 2014/2015
Inserção de um novo elemento: insert
20
12 32
8 18 23 45
2 9
9 IAED, 2014/2015
Inserção de um novo elemento: insert
• Começo na raiz
• Vou percorrendo a árvore de cima para baixo até
encontrar o lugar onde introduzir o novo elemento
• Quando encontrar o lugar vazio (NULL) para o novo
elemento (respeitando as regras da binary search tree)
crio um novo elemento.
• Mais uma vez, podemos fazer isto recursivamente...
10 IAED, 2014/2015
Inserção de um novo elemento: insert
11 IAED, 2014/2015
Como encontrar o menor elemento abaixo de
um determinado nó?
• Como fazer?
• Descemos a árvore sempre pelo filho da esquerda até
encontrarmos um nó sem filho esquerdo
20
12 32
8 18 23 45
12 IAED, 2014/2015
Como encontrar o maior elemento abaixo de
um determinado nó?
• Descemos a árvore sempre pelo filho da direita até
encontrarmos um nó sem filho na direita
20
12 32
8 18 23 45
13 IAED, 2014/2015
Max & Min
link max(link h) {
if (h==NULL || h->r==NULL) return h;
else return max(h->r);
}
link min(link h) {
if (h==NULL || h->l==NULL) return h;
else return min(h->l);
}
14 IAED, 2014/2015
Max & Min (alternativa)
link max(link h) {
while(h!=NULL && h->r!=NULL)
h=h->r;
return h;
}
link min(link h) {
while(h!=NULL && h->l!=NULL)
h=h->l;
return h;
}
15 IAED, 2014/2015
Remoção de um elemento
• Mais difícil: 3 possibilidades.
1. Se o nó não tiver filhos à fácil... Basta apagar.
2. Se o nó tiver um único filho... Também é fácil.
ex: apagar o 18. Redirecionamos o filho direito do
12 para o 19 e apagamos o 18.
20
12 32
8 18 23 45
16 2 9 19 IAED, 2014/2015
Remoção de um elemento
• Mais difícil: 3 possibilidades.
1. Se o nó não tiver filhos à fácil... Basta apagar.
2. Se o nó tiver um só filho... Também é fácil.
ex: apagar o 18. Redirecionamos o filho direito do
12 para o 19 e apagamos o 18.
20
12 32
8 19 23 45
17 2 9 19 IAED, 2014/2015
Remoção de um elemento
• Mais difícil: 3 possibilidades.
1. Se o nó não tiver filhos à fácil... Basta apagar.
2. Se o nó tiver um só filho... Também é fácil.
3. Remoção de um nó interno: i) substituímos o elemento
a remover pelo maior dos elementos à esquerda do
elemento a ser removido.
20
12 32
8 18 23 45
18 2 9 19 IAED, 2014/2015
Remoção de um elemento
• Mais difícil: 3 possibilidades.
1. Se o nodo não tiver filhos à fácil... Basta apagar.
2. Se o nodo tiver um só filho... Também é fácil.
3. Remoção de um nó interno: i) substituímos o elemento
a remover pelo maior dos elementos à esquerda do
elemento a ser removido. ii) removemos esse elemento
(que estará nas condições 1 ou 2)
20
9 32
8 18 23 45
19 2 9 19 IAED, 2014/2015
Delete
link delete(link h, Item item) {
link aux ;
if (h==NULL) return h;
else if (less(item, h->item)) h->l=delete(h->l,item);
else if (less(h->item, item)) h->r=delete(h->r,item);
else{
if ( h->l !=NULL && h->r !=NULL ) { /*caso 3*/
aux=max(h->l);
h->item = aux->item;
h->l=delete(h->l, aux->item);
}
else { /*casos 1 e 2*/
aux=h;
if ( h->l == NULL && h->r == NULL ) h=NULL;
else if (h->l==NULL) h=h->r;
else h=h->l;
deleteItem(aux->item);
free(aux);
}
20
}
return h;
IAED, 2014/2015
}
Número de Elementos e Profundidade
int count(link h) {
if (h==NULL) return 0;
else
return count(h->r) + count(h->l) + 1;
}
int height(link h)
{
int u, v;
if (h == NULL) return 0;
u = height(h->l);
v = height(h->r);
if (u > v) return u+1;
else return v+1;
}
Nota: Aqui estamos considerar que a profundidade de uma folha é igual a 1.
Também é comum considerar que esta é igual a 0. Nesse caso, quando
h==NULL, a função deverá retornar -1, ou seja, ...
IAED, 2014/2015
21
Número de Elementos e Profundidade
int count(link h) {
if (h==NULL) return 0;
else
return count(h->r) + count(h->l) + 1;
}
int height(link h)
{
int u, v;
if (h == NULL) return -1;
u = height(h->l);
v = height(h->r);
if (u > v) return u+1;
else return v+1;
}
22 IAED, 2014/2015
Funçao visit
23 IAED, 2014/2015
Travessia em Pre-Order
void traverse(link h)
20
{
if (h == NULL) 12 32
return;
visit(h->item);
traverse(h->l); 8 18 23 45
traverse(h->r);
} 2 9
24 IAED, 2014/2015
Outra alternativa…
void traverse(link h)
20
{
if (h == NULL) 12 32
return;
traverse(h->l);
visit(h); 8 18 23 45
traverse(h->r);
} 2 9
25 IAED, 2014/2015
Travessia em In-Order (sorted!!)
void traverse(link h)
20
{
if (h == NULL) 12 32
return;
traverse(h->l);
visit(h); 8 18 23 45
traverse(h->r);
} 2 9
26 IAED, 2014/2015
Travessia em Post-Order
27 IAED, 2014/2015
Pesquisas em BST
Porquê?
• Geralmente eficiente: O(log N )
• No pior caso, O( N ) para uma árvore desequilibrada
– Ordem de inserção: 1,2,3,4,5,6,7,8
• No caso de chaves aleatórias, O(log N )
Porquê?
• Comparação com pesquisa binária em tabelas:
– Tempo de pesquisa comparável
– Tempo de inserção muito mais rápido
• Tempo de pesquisa e inserção são O( N ) no pior caso
(árvore degenerada)
28 IAED, 2014/2015
Árvores Binárias Equilibradas
29 IAED, 2014/2015
Exercício de exame: árvores binárias
III.b) Considere a seguinte árvore binária de pesquisa:
Solução: -6 1 0 4 15 26 50 52 37 24 12
Solução: -6 1 0 4 15 26 50 52 37 24 12
IAED, 2014/2015
Exercício de exame: árvores binárias
Considere uma árvore binária de pesquisa t, que permite guardar
número inteiros.
Assumindo que a árvore está inicialmente vazia, indique
i) o resultado de uma travessia pre-order depois de inserir os
seguintes elementos: {11, 15, 8, 5, 9, 1, 18}.
ii) Qual o resultadado de uma travessia post-order depois de
remover o elemento 11 ?
IAED, 2014/2015
Exercício de exame: árvores binárias
Considere uma árvore binária de pesquisa t, que permite guardar
número inteiros.
Assumindo que a árvore está inicialmente vazia, indique
i) o resultado de uma travessia pre-order depois de inserir os
seguintes elementos: {11, 15, 8, 5, 9, 1, 18}.
ii) Qual o resultadado de uma travessia post-order depois de
remover o elemento 11 ?
11
8 15
5 9 18
8 15
5 9 18
1
IAED, 2014/2015
Exercício de exame: árvores binárias
Considere uma árvore binária de pesquisa t, que permite guardar
número inteiros.
Assumindo que a árvore está inicialmente vazia, indique
i) o resultado de uma travessia pre-order depois de inserir os
seguintes elementos: {11, 15, 8, 5, 9, 1, 18}.
ii) Qual o resultadado de uma travessia post-order depois de
remover o elemento 11 ?
9
8 15
5 9 18
1
IAED, 2014/2015
Exercício de exame: árvores binárias
Considere uma árvore binária de pesquisa t, que permite guardar
número inteiros.
Assumindo que a árvore está inicialmente vazia, indique
i) o resultado de uma travessia pre-order depois de inserir os
seguintes elementos: {11, 15, 8, 5, 9, 1, 18}.
ii) Qual o resultadado de uma travessia post-order depois de
remover o elemento 11 ?
9
8 15
5 18
8 15
5 9 18
1
IAED, 2014/2015
Alternativa (olhar para a árvore esquerda)
Considere uma árvore binária de pesquisa t, que permite guardar
número inteiros.
Assumindo que a árvore está inicialmente vazia, indique
i) o resultado de uma travessia pre-order depois de inserir os
seguintes elementos: {11, 15, 8, 5, 9, 1, 18}.
ii) Qual o resultadado de uma travessia post-order depois de
remover o elemento 11 ?
15
8 18
5 9
Cada nó da árvore binária deverá ser representado por uma estrutura do tipo:
38 IAED, 2014/2015
Item.h
#ifndef _ITEM_ a chave pela
#define _ITEM_
qual vamos arrumar
#include <stdio.h> os elementos é o
#include <stdlib.h> nome
#include <string.h>
void deleteItem(Item a)
{
free(a->nome);
free(a);
}
void visitItem(Item a)
40
{
printf("nome: %s\n",a->nome);
printf("notaIAED: %d\n",a->notaIAED);
printf("curso: %d\n\n",a->curso);
}
IAED, 2014/2015
Interface do ADT Tabela de Símbolos
ST.h
#ifndef _ST_
#define _ST_
#include <stdlib.h>
#include <stdio.h>
#include "Item.h"
void STinit(link*);
int STcount(link);
Item STsearch(link, Key);
void STinsert(link*, Item);
void STdelete(link*, Key);
void
41 STsort(link, void (*visit)(Item));
void STfree(link*);
IAED, 2014/2015
#endif
ST.c
#include "ST.h"
void STinit(link*head)
{
*head = NULL;
}
42
IAED, 2014/2015
ST.c
IAED, 2014/2015
ST.c
IAED, 2014/2015
ST.c
link deleteR(link h, Key k)
{
if (h==NULL) return h;
else if (less(k, key(h->item))) h->l=deleteR(h->l,k);
else if (less(key(h->item), k)) h->r=deleteR(h->r,k) ;
else {
if (h->l !=NULL && h->r !=NULL){/*caso 3*/
link aux=max(h->l);
{Item x; x=h->item; h->item=aux->item; aux->item=x; }
h->l= deleteR(h->l, key(aux->item));
}
else { /*casos 1 e 2*/
link aux=h;
if ( h->l == NULL && h->r == NULL ) h=NULL;
else if (h->l==NULL) h=h->r; Esta função
else h=h->l; também
deleteItem(aux->item); poderia ter sido
45
free(aux); passada como
}
}
argumento
return h;
}
IAED, 2014/2015
ST.c
link max(link h) {
if (h==NULL || h->r==NULL) return h;
else return max(h->r);
}
46
void STdelete(link*head, Key k){
*head = deleteR(*head, k);
}
IAED, 2014/2015
ST.c
47
IAED, 2014/2015
ST.c
link freeR(link h)
{
if (h==NULL)
return h;
h->l=freeR(h->l);
h->r=freeR(h->r);
return deleteR(h,key(h->item));
}
void STfree(link*head)
{
*head=freeR(*head);
}
48
IAED, 2014/2015
main.c
#include <stdio.h>
#include "ST.h"
int main(){
link turma1;
STinit(&turma1);
STsort(turma1,visitItem);
STfree(&turma1);
return 0;
IAED, 2014/2015
}
Próxima aula
50 IAED, 2014/2015
Grafos (I)
CLRS: Capítulo 22
IAED, 2014/2015
Grafos
• Definição e representação
– Matriz de adjacências
– Listas de Adjacências
• Interface do ADT Grafo
• Implementação do ADT Grafo usando
– Matriz de adjacências
– Listas de Adjacências
• Matrizes adjacências vs Listas de adjacências
3 IAED, 2014/2015
Grafo - Definição
vértice / nó
arco / link / aresta
4 IAED, 2014/2015
Grau de um nó
• O grau de um vértice (d, degree) contabiliza o número de
ligações/arcos de um vértice (ou nodo).
• O grau médio de um grafo (z), é a média dos graus de
todos os vértices
d=1
vértice / nó
arco / link / aresta
d=1
d=2
d=1 d=0
d=1
d=3
d=3
d=1
d=4
• Grafo Dirigido
– Os arcos podem ter direcção
• Grafo Pesado
2
– Os arcos podem ter peso (custo)
3
4
5 3
2 3
3 5
1 4
6 IAED, 2014/2015
Outros Conceitos
• Grafo conexo
– Para quaisquer vértices v e u, há
sempre o caminho a ligar u e v
7 IAED, 2014/2015
Outros Conceitos
• Bi-connected graphs
– para qualquer vértice v, se
removermos v, o grafo continua
conexo
• Grafo conexo
– Para quaisquer vértices v e u, há
sempre o caminho a ligar u e v
8 IAED, 2014/2015
Exemplos de grafos
IAED, 2014/2015
Francisco C. Santos, IST, 2012
Exemplos de grafos o sistema nervoso do planeta
vértices arestas
routers linhas telefónicas
satélites cabos de TV
computadores ondas EM
IAED, 2014/2015
#1 Eric Roberts (I)
#411
Kevin Bacon
#2 Michael Madsen
IAED, 2014/2015
Representação: listas
dirigido 1 2 3 4
1 3 1 0 1 0 1
2 0 0 1 0
3 0 0 0 0
2 4 4 0 1 0 0
15 IAED, 2014/2015
Matriz de Adjacências - Vantagens
16 IAED, 2014/2015
Matriz de Adjacências - Inconvenientes
17 IAED, 2014/2015
Listas de Adjacências - Vantagens
• Inicialização é proporcional a V
18 IAED, 2014/2015
Listas de Adjacências - Inconvenientes
• Remoção de arcos
– Pode levar um tempo proporcional a V (este problema pode ser
contornado).
19 IAED, 2014/2015
Representações Alternativas
20 IAED, 2014/2015
Grafos - Definição e Representação
21 IAED, 2014/2015
Grafos - Definição e Representação
• Listas de adjacências
– Grafos não dirigidos
• Tamanho das listas é 2 ⋅⏐E⏐
– Grafos dirigidos
• Tamanho das listas é⏐E⏐
∴ Tamanho total das listas de adjacências é O(V+E)
– Matriz de adjacências: Θ(V 2 ) para qualquer grafo
• Grafos pesados
– Função de pesos: w: E → R
• Permite associar um peso a cada arco
22 IAED, 2014/2015
Interface do ADT Grafo
GRAPH.h Estrutura auxiliar
typedef struct { Edge
int v;
int w; Devolve um Edge
} Edge; ligando x e y
Graph GRAPHinit(int);
void GRAPHinsertE(Graph, Edge);
void GRAPHremoveE(Graph, Edge);
int GRAPHedges(Edge a[], Graph G);
Graph GRAPHcopy(Graph);
void GRAPHdestroy(Graph);
23 IAED, 2014/2015
Implementação do ADT Grafo - Matriz
GRAPHmat.c
#include <stdlib.h>
#include “GRAPH.h” número de vértices
e arcos
typedef struct graph {
int V, E;
int **adj;
matriz de inteiros
} * Graph;
25 IAED, 2014/2015
Implementação do ADT Grafo - Matriz
GRAPHmat.c (cont)
26 IAED, 2014/2015
Implementação do ADT Grafo - Listas
GRAPHlst.c
#include <stdlib.h>
#include “GRAPH.h”
struct graph {
int V;
int E; vector de
link *adj; listas ligadas
};
27 IAED, 2014/2015
Implementação do ADT Grafo - Listas
GRAPHlst.c (cont)
link NEW(int v, link next) { função chamada
link x = malloc(sizeof(struct node)); quando adiciono um
x->v = v; vértice
x ->next = next; cada novo elemento
return x;
é inserido no início
}
Graph GRAPHinit(int V) {
int v; reservo memória
G = malloc(sizeof(struct graph)); para V links, ou seja,
G->V = V;
para V nós
G->E = 0;
G->adj = malloc(V * sizeof(link));
for (v = 0; v < V; v++)
G->adj[v] = NULL;
inicializo todos
return G;
} a NULL
28 IAED, 2014/2015
Implementação do ADT Grafo - Listas
GRAPHlst.c (cont)
} ver aula de
listas ligadas
29 IAED, 2014/2015
Implementação do ADT Grafo - Listas
GRAPHlst.c (cont) Função que recebe um G e retorna um
vector e um nº de Edges
ciclo sobre
int GRAPHedges(Edge a[], Graph G) {
todos os vértices
int v, E = 0;
link t;
for (v = 0; v < G->V; v++) percorre a lista
for (t = G->adj[v]; t != NULL; t = t->next)
de adjacentes de v
if (v < t->v )
a[E++] = EDGE(v, t->v); para
return E; evitar elementos
} repetidos só adiciono
devolve lista pares onde
com todos os v < t->v
arcos do grafo
30 IAED, 2014/2015
Desempenho das Várias Representações
E = nº de arestas ; V = nº de vértices
31 IAED, 2014/2015
Desempenho das Várias Representações
E = nº de arestas ; V = nº de vértices
32 IAED, 2014/2015
Procura
34 IAED, 2014/2015
Procura
origem
36 IAED, 2014/2015
Procura em Largura Primeiro (BFS)
Breadth-First
Search
• Visita os vértices por ordem da sua distância à origem
• Vértices mais próximos são visitados em primeiro lugar
– Vértices não atingíveis a partir da origem, não são visitados
origem
37 IAED, 2014/2015
Procura em Largura Primeiro (BFS)
Breadth-First
Search
• Visita os vértices por ordem da sua distância à origem
• Vértices mais próximos são visitados em primeiro lugar
– Vértices não atingíveis a partir da origem, não são visitados
origem
origem
38 IAED, 2014/2015
Procura em Largura Primeiro (BFS)
Breadth-First
Search
• Dados G = (V, E) e vértice fonte s, BFS explora
sistematicamente vértices de G para descobrir todos os
vértices atingíveis a partir de s
– Cálculo da distância: menor número de arcos de s para cada vértice
atingível
– Identificação de árvore BF: caminho mais curto de s para cada
vértice atingível v
• Fronteira entre nós descobertos e não descobertos é
expandida uniformemente
– Vértices à distância k descobertos antes de qualquer vértice à
distância k+1
39 IAED, 2014/2015
Procura em Largura Primeiro (BFS) O BFS depende
da ordem das listas
• Exemplo 1:
Lista adjacente:
A A: B, C, D
B: E
B C D C: B, G
D: C, G
E: C, F
E F G F: C, H
G: F, H, I
H: E, I
I: F
H I
Sequência: A B C D E G F H I
Distância: 0 1 1 1 2 2 3 3 3
IAED, 2014/2015
40
Procura em Largura Primeiro (BFS trees)
• Exemplo 1:
Lista adjacente:
A A
A: B, C, D
B: E
B C D C:BB, G C D
D: C, G
E: C, F
E F G F:E C, H G
G: F, H, I
H: E, I
I: F
F H I
H I
Sequência: A B C D E G F H I
Distância: 0 1 1 1 2 2 3 3 3
Predecessores: NIL A A A B C E G G
(ou pais) IAED, 2014/2015
41
Procura em Largura Primeiro (BFS)
• Aplicações
– Encontrar as componentes conexas de um grafo.
– Encontrar todos os nós de uma componente conexa.
– Encontrar todos os caminhos mais curtos entre 2 nós, u e v,
de um grafo sem pesos ou com pesos (grafo pesado).
42 IAED, 2014/2015
Procura em Largura Primeiro (BFS)
• Implementação
– color[v]: cor do vértice v, branco, cinzento e preto
• branco: não visitado
• cinzento: já visitado mas algum dos adjacentes não visitado ou
procura em algum dos adjacentes não terminada
• preto: já visitado e procura nos adjacentes já terminada
– π[v]: predecessor de v na árvore BF
– d[v]: tempo de descoberta de v
• Outras definições
– δ (s,v): menor distância de s a v - menor número de arcos em
qualquer caminho de s para v
43 IAED, 2014/2015
Procura em Largura Primeiro (BFS)
Inicializa cores, d’s e
predecessores de todos
os nós
Inicializa a “source”
Function BFS (G, src)
Quando testamos,
for each u ∈ V[G]
Q guarda sempre os color[u] = white; d[u] = ∞; π[u] = NIL inicializações
cinzentos
color[src] = gray; d[src] = 0; π[src] = NIL
Q = { src } Inicializa a fila de espera
while Q ≠ ∅
Vai buscar o 1º elem.
u = Dequeue (Q)
ciclo for each v ∈ Adj[u] Para todos
principal os parceiros v de u
if color[v] = white then
color[v] = gray; d[v] = d[u] + 1; π[v] = u
Enqueue (Q, v)
color[u] = black Se forem brancos,
pinta de cinzento,
...no fim, tornamos u Coloca cada v, na fila incrementa d e coloca
44
“preto” (=processado) de espera u como “pai”
IAED, 2014/2015
Exemplo BFS
v w x y
d[v]=∞ d[w]=∞ d[x]=∞ d[y]=∞
π[v]=NIL π[w]=NIL π[x]=NIL π[y]=NIL
45 IAED, 2014/2015
Exemplo BFS
v w x y
d[v]=∞ d[w]=1 d[x]=∞ d[y]=∞
π[v]=NIL π[w]=s π[x]=NIL π[y]=NIL
46 IAED, 2014/2015
Exemplo BFS
47 IAED, 2014/2015
Exemplo BFS
48 IAED, 2014/2015
Exemplo BFS
49 IAED, 2014/2015
Exemplo BFS
50 IAED, 2014/2015
Exemplo BFS
v w x y
d[v]=2 d[w]=1 d[x]=2 d[y]=3
π[v]=r π[w]=s π[x]=w π[y]=x
51 IAED, 2014/2015
Exemplo BFS
v w x y
d[v]=2 d[w]=1 d[x]=2 d[y]=3
π[v]=r π[w]=s π[x]=w π[y]=x
52 IAED, 2014/2015
Exemplo BFS
v w x y
d[v]=2 d[w]=1 d[x]=2 d[y]=3
π[v]=r π[w]=s π[x]=w π[y]=x
53 IAED, 2014/2015
Exemplo BFS
s
d[r]=1 d[s]=0 d[t]=2 d[u]=3
π[r]=s π[s]=NIL π[t]=w π[u]=t
r s t u r w
v w x y v t x
d[v]=2 d[w]=1 d[x]=2 d[y]=3
π[v]=r π[w]=s π[x]=w π[y]=x
u y
54 IAED, 2014/2015
Implementação de BFS - Matriz de Adj.
55 IAED, 2014/2015
Exercício: Travessia Largura Primeiro (BFS)
56 A B C G D E H F IAED, 2014/2015
Procura em Largura Primeiro (BFS)
• Tempo de execução
57 IAED, 2014/2015
Procura em Largura Primeiro (BFS)
• Resultado
( ) ( )
– Para qualquer arco (u,v): δ s ,v ≤ δ s , u + 1
• Se u atingível, então v atingível
– Caminho mais curto para v não pode ser superior a caminho
mais curto para u mais o arco (u,v)
• Se u não atingível, então resultado é válido (independentemente de
v ser atingível)
• No final da BFS
– d[u] = δ(s,u), para todo o vértice u de V
58 IAED, 2014/2015
Procura em Profundidade Primeiro (DFS)
Depth-First
Search
• Visita primeiro os arcos dos vértices mais recentemente
visitados
origem
59 IAED, 2014/2015
Procura em Profundidade Primeiro (DFS)
Depth-First
Search
• Visita primeiro os arcos dos vértices mais recentemente
visitados
origem origem
60 IAED, 2014/2015
Procura em Profundidade Primeiro (DFS)
• Aplicações
– Encontrar um caminho entre 2 nodos específicos, u e v, num
grafo sem pesos ou com pesos (grafo pesado).
– Saber se um grafo é conexo ou não.
– Útil para saber a ordenação topológica de um grafo
61 IAED, 2014/2015
Procura em Profundidade Primeiro (DFS)
• Implementação:
– color[u]: cor do vértice (branco, cinzento, preto)
– d[u]: tempo de início (de visita do vértice)
– f[u]: tempo de fim (de visita do vértice)
– π[u]: predecessor
62 IAED, 2014/2015
Procura em Profundidade Primeiro (DFS)
Inicialização
Pinta de cinzento
u v w
Time=0
x y z
d[x]=∞ d[y]=∞ d[z]=∞
f[x]=∞ f[y]=∞ f[z]=∞
π[x]=NIL π[y]=NIL π[z]=NIL
64 IAED, 2014/2015
Exemplo DFS
u v w
Time=1
x y z
d[x]=∞ d[y]=∞ d[z]=∞
f[x]=∞ f[y]=∞ f[z]=∞
π[x]=NIL π[y]=NIL π[z]=NIL
65 IAED, 2014/2015
Exemplo DFS
u v w
Time=2
x y z
d[x]=∞ d[y]=∞ d[z]=∞
f[x]=∞ f[y]=∞ f[z]=∞
π[x]=NIL π[y]=NIL π[z]=NIL
66 IAED, 2014/2015
Exemplo DFS
u v w
Time=3
x y z
d[x]=∞ d[y]=3 d[z]=∞
f[x]=∞ f[y]=∞ f[z]=∞
π[x]=NIL π[y]=v π[z]=NIL
67 IAED, 2014/2015
Exemplo DFS
u v w
Time=4
x y z
d[x]=4 d[y]=3 d[z]=∞
f[x]=∞ f[y]=∞ f[z]=∞
π[x]=y π[y]=v π[z]=NIL
68 IAED, 2014/2015
Exemplo DFS
u v w
B
Time=5
x y z
d[x]=4 d[y]=3 d[z]=∞
f[x]=∞ f[y]=∞ f[z]=∞
π[x]=y π[y]=v π[z]=NIL
69 IAED, 2014/2015
Exemplo DFS
u v w
B
Time=5
x y z
d[x]=4 d[y]=3 d[z]=∞
f[x]=5 f[y]=∞ f[z]=∞
π[x]=y π[y]=v π[z]=NIL
70 IAED, 2014/2015
Exemplo DFS
u v w
B
Time=6
x y z
d[x]=4 d[y]=3 d[z]=∞
f[x]=5 f[y]=6 f[z]=∞
π[x]=y π[y]=v π[z]=NIL
71 IAED, 2014/2015
Exemplo DFS
u v w
B
Time=7
x y z
d[x]=4 d[y]=3 d[z]=∞
f[x]=5 f[y]=6 f[z]=∞
π[x]=y π[y]=v π[z]=NIL
72 IAED, 2014/2015
Exemplo DFS
u v w
B
Time=8 F
x y z
d[x]=4 d[y]=3 d[z]=∞
f[x]=5 f[y]=6 f[z]=∞
π[x]=y π[y]=v π[z]=NIL
73 IAED, 2014/2015
Exemplo DFS
u v w
B
Time=9 F
x y z
d[x]=4 d[y]=3 d[z]=∞
f[x]=5 f[y]=6 f[z]=∞
π[x]=y π[y]=v π[z]=NIL
74 IAED, 2014/2015
Exemplo DFS
u v w
B C
Time=9 F
x y z
d[x]=4 d[y]=3 d[z]=∞
f[x]=5 f[y]=6 f[z]=∞
π[x]=y π[y]=v π[z]=NIL
75 IAED, 2014/2015
Exemplo DFS
u v w
B C
Time=10 F
x y z
d[x]=4 d[y]=3 d[z]=10
f[x]=5 f[y]=6 f[z]=∞
π[x]=y π[y]=v π[z]=w
76 IAED, 2014/2015
Exemplo DFS
u v w
B C
Time=11 F
x y z B
77 IAED, 2014/2015
Exemplo DFS
u v w
B C
Time=12 F
x y z B
78 IAED, 2014/2015
Exemplo DFS
u v w
B C
Time=12 F
x y z B
79 IAED, 2014/2015
Exemplo DFS
u w
v z
x
80 IAED, 2014/2015
Procura em Profundidade Primeiro (DFS)
• Exemplo (origem: ‘A’):
Lista adjacente (ordem alfab.):
A A: B, C
B: E O DFS depende
B C D C: B, F da ordem das listas
D: C, G
E: F
E F G F:
G: F
A D
B C G
Sequência: A B E F C D G
Predecessor: nil A B E A nil D E
F
IAED, 2014/2015
81
Procura em Profundidade Primeiro (DFS)
• Exemplo (origem: ‘A’):
Lista adjacente (ordem alfab.):
1/ 10 A A: B, C
8/ 9 11/ 14 B: E O DFS depende
2/ 7
B C D C: B, F da ordem das listas
D: C, G
3/ 6 4/ 5 12/ 13
E: F
E F G F:
G: F
Sequência: A B E F C D G
Tempo de descoberta: 1 2 3 4 8 11 12
Tempo de fim: 10 7 6 5 9 14 13
IAED, 2014/2015
82
Implementação de DFS
83 IAED, 2014/2015
Exercício: Travessia Profundidade Primeiro (DFS)
ACBFEDG
84 IAED, 2014/2015
Procura em Profundidade Primeiro (DFS)
∑ | Adj[v] |= Θ( E )
v∈V
85 IAED, 2014/2015
Grafos (II)
CLRS: Capítulos 22 e 23
IAED, 2014/2015
Mais uns conceitos úteis
v2
v5
87 IAED, 2014/2015
Mais uns conceitos úteis
88 IAED, 2014/2015
Mais uns conceitos úteis
– No grafo em baixo existem 2 ciclos (azul e verde)
90 IAED, 2014/2015
Ordenação Topológica: Exemplo
undershorts socks
watch
pants shoes
shirt
belt
tie
jacket
91 IAED, 2014/2015
Exercício: ordenação topológica
a. <A,B,C,D,E,F,G>
b. <B,A,D,C,G,F,E>
c. <B,A,D,F,E,G,C>
d. <B,F,A,E,D,C,G>
e. <C,G,E,B,A,D,F>
f. <F,E,G,D,C,B,A>
g. <F,G,E,B,A,D,C>
92 IAED, 2014/2015
Exercício: ordenação topológica
a. <A,B,C,D,E,F,G>
b. <B,A,D,C,G,F,E>
c. <B,A,D,F,E,G,C>
d. <B,F,A,E,D,C,G>
e. <C,G,E,B,A,D,F>
f. <F,E,G,D,C,B,A>
g. <F,G,E,B,A,D,C>
93 IAED, 2014/2015
Exercício: ordenação topológica
a. <A,B,C,D,E,F,G>
b. <B,A,D,C,G,F,E>
c. <B,A,D,F,E,G,C>
d. <B,F,A,E,D,C,G>
e. <C,G,E,B,A,D,F>
f. <F,E,G,D,C,B,A>
g. <F,G,E,B,A,D,C>
94 IAED, 2014/2015
Exercício: ordenação topológica
a. <A,B,C,D,E,F,G>
b. <B,A,D,C,G,F,E>
c. <B,A,D,F,E,G,C>
d. <B,F,A,E,D,C,G>
e. <C,G,E,B,A,D,F>
f. <F,E,G,D,C,B,A>
g. <F,G,E,B,A,D,C>
95 IAED, 2014/2015
Exercício: ordenação topológica
a. <A,B,C,D,E,F,G>
b. <B,A,D,C,G,F,E>
c. <B,A,D,F,E,G,C>
d. <B,F,A,E,D,C,G>
e. <C,G,E,B,A,D,F>
f. <F,E,G,D,C,B,A>
g. <F,G,E,B,A,D,C>
96 IAED, 2014/2015
Exercício: ordenação topológica
a. <A,B,C,D,E,F,G>
b. <B,A,D,C,G,F,E>
c. <B,A,D,F,E,G,C>
d. <B,F,A,E,D,C,G>
e. <C,G,E,B,A,D,F>
f. <F,E,G,D,C,B,A>
g. <F,G,E,B,A,D,C>
97 IAED, 2014/2015
Exercício: ordenação topológica
a. <A,B,C,D,E,F,G>
b. <B,A,D,C,G,F,E>
c. <B,A,D,F,E,G,C>
d. <B,F,A,E,D,C,G>
e. <C,G,E,B,A,D,F>
f. <F,E,G,D,C,B,A>
g. <F,G,E,B,A,D,C>
98 IAED, 2014/2015
Exercício: ordenação topológica
a. <A,B,C,D,E,F,G>
b. <B,A,D,C,G,F,E>
c. <B,A,D,F,E,G,C>
d. <B,F,A,E,D,C,G>
e. <C,G,E,B,A,D,F>
f. <F,E,G,D,C,B,A>
g. <F,G,E,B,A,D,C>
99 IAED, 2014/2015
Ordenação Topológica
• Algoritmos
– Utilizando informação de DFS
– Eliminação de vértices (não vamos estudar)
belt
6/7 tie 2/ 5
jacket 3/ 4
18 16 15 14 10 8 7 5 4
5/ 6
2/ 7 A C
A C
3/ D
4 D
Indique
Indique uma
uma ordenação
ordenação topológica
topológica dos vértices
dos vértices do grafo.do grafo.
Solução:
Solução:
⟨B, A,A,
C, D⟩
B A C D
⟨B, C, D⟩ IAED, 2014/2015
104
Considere o seguinte grafo orientado.
Exercício:
IV.b) DFS &
IV.b)Considere
ordenação
Considereooseguinte
seguintegrafo
topológica
grafoorientado.
orientado.
IV.b) Considere o seguinte grafo orientado.
1/ 10 5/D
8
A AC
A CC D D
A C 4/ D
9
BB EE
2/ 3 B E
B E 6/ 7
• Definição:
– Dado o grafo dirigido G = (V, E) um componente fortemente
ligado (SCC) é um conjunto máximo de vértices U ⊆ V, tal que
para u,v∈U, u é atingível a partir de v, E v é atingível a partir de
u
• Obs: um vértice simples é um SCC
• Outras definições:
– Grafo transposto de G = (V, E)
• GT = (V, ET) tal que: ET = {(u, v ) : ( v, u ) ∈ E}
1 2-4-5 3-6
4 6
5
7 8
7-8-9-10-11-12
10
11
12
• Resposta: 3
• Resposta: 2
Solução: 1
L R
grafo bipartido
117 IAED, 2014/2015
Desafio!
BFS ?
3
1 BFS ?
0
2
5
2
3
4
6
3 5
3
1 BFS
0
2
5
2
3
4
6
3 5
BFS ?
3
1 BFS
0
2
2
3
4
3 4
3
1 BFS
0
2
2
3
4
3 4
IAED, 2014/2015
Grafos: BFS (travessia
Grupo IV (1.0+1.5+1.5 = 4.0 val.) em largura primeiro)
IV.a) Considere uma travessia em largura primeiro (BFS) sobre o grafo G = (V, E) abaixo, com
origem no vértice A. Considere ainda que os vértices são visitados por ordem alfabética e que os
vértices adjacentes de um vértice são também visitados por ordem alfabética. Quais os valores de
d[v] para cada um dos vértices v ∈ V no final da travessia?
C B A
D E F
G H
Solução:
A B C D E F G H
0 1 2 3 4 1 4 2
IAED, 2014/2015
C B A
Grafos: BFS (travessia
Grupo IV (1.0+1.5+1.5 = 4.0 val.) em largura primeiro)
IV.a) Considere uma travessia em largura primeiro (BFS) sobre o grafo G = (V, E) abaixo, com
origem no vértice A. Considere ainda que os vértices são visitados por ordem alfabética e que os
vértices adjacentes de um vértice são também visitados por ordem alfabética. Quais os valores de
d[v] para cada um dos vértices v ∈ V no final da travessia?
2 1 0
C BD A E F
4 1
3
D E F
G H
4
G H
2
Solução:
Solução:
A B C D E
A0 1 2 3
B C 4
DF1 G H
E
4 2
F G H
IAED, 2014/2015
0 1 2 3 4 1 4 2
Grafos:
) Considere Ordenação
o grafo da figura em topológica
baixo. Indique uma (c/DFS)
sequência de vértice
ordenação topológica
IV.c) Considere o grafo dado grafo.
figura em baixo. Indique uma sequência de vértices que corresponda a
uma ordenação topológica do grafo.
A A B B E E
C D F
C D F
G H
Solução:
Existem várias ordenações topológicas possı́veis.
G A, C >.
Uma solução seria a seguinte sequência: < D, E, F, H, G, B, H
IAED, 2014/2015
Outra solução poderia ser a sequência: < D, E, B, A, F, H, G, C >.
IV.c) Considere o grafo da figura em baixo. Indique uma sequência de vértices que corresp
uma ordenação topológica do grafo.
Grafos:
) Considere Ordenação
o grafo da figura em topológica
baixo. Indique uma (c/DFS)
sequência de vértice
ordenação topológica
IV.c) Considere o grafo dado grafo.
figura A
em baixo. IndiqueBuma sequência de
E vértices que corresponda a
uma ordenação topológica do grafo.
2/ 7 8/ 15
3/ 6
A A B B E E
C D F
C D F
4/ 5 1/16 9/ 14
C D F
G H
G H
Solução:
Existem várias ordenações topológicas possı́veis.
Uma solução seria a seguinte sequência: < D, E, F, H, G, B, A, C >.
Solução: 12/ 13
Existem
Outra váriaspoderia
solução ordenações
sertopológicas possı́veis.
a sequência: < D, E, 10/B,
11 A, F, H, G, C >.
DE F H G B A C G A, C >.
Uma solução seria a seguinte sequência: < D, E, F, H, G, B,
Outra solução poderia ser a sequência: < D, E, B, A, F, H, G, C >.
H
IAED, 2014/2015
SCCs
A C F
E H
B D G
Solução: 3
IAED, 2014/2015
SCCs
A C F
E H
B
B D G
Solução: 3
A B E F
D G
Indique os tempos de descoberta d e de finalização f , para cada um dos vértices, após a execução
de uma procura em profundidade primeiro (DFS), onde os vértices são considerados por ordem
lexicográfica (ou seja, A, B, C, . . .). Qual é a ordenaçao topológica obtida pela DFS para o grafo
acima?
Solução:
Vértice A B C D E F G
d 1 2 3 9 4 5 10
f 14 13 8 12 7 6 11
Ord. Topológica A B D G C E F
IAED, 2014/2015
III.b) ToDo Considere o seguinte grafo dirigido.
3/ 8
C
1/ 14 2/ 13 4/ 7 5/
6
A B E F
D G
9/12
10/11
Indique os tempos de descoberta d e de finalização f , para cada um dos vértices, após a execução
de uma procura em profundidade primeiro (DFS), onde os vértices são considerados por ordem
lexicográfica (ou seja, A, B, C, . . .). Qual é a ordenaçao topológica obtida pela DFS para o grafo
acima?
Solução:
Vértice A B C D E F G
d 1 2 3 9 4 5 10 A
f 14 13 8 12 7 6 11
B D G C E F
Ord. Topológica A B D G C E F
IAED, 2014/2015
III.b) ToDo Considere o seguinte grafo dirigido.
3/ 8 C
A
2/ 13 B 4/ 7 E5/ F
1/ 14 6
A B E F
D G
D G
9/12
10/ 11 um dos vértices, após a ex
Indique os tempos de descoberta d e de finalização f , para cada
de uma procura em profundidade primeiro (DFS), onde os vértices são considerados por
Indique os tempos de descoberta d e de finalização f , para cada um dos vértices, após a execução
lexicográfica
de uma procura (ou seja, A,primeiro
em profundidade .). Qualonde
B, C, . . (DFS), é a os
ordenaçao topológica
vértices são obtidapor
considerados pela DFS para
ordem
acima?
lexicográfica (ou seja, A, B, C, . . .). Qual é a ordenaçao topológica obtida pela DFS para o grafo
acima?
Solução:
Solução:
Vértice A B C D E F G
Vértice A dB C 1 D 2 E 3 F 9G 4 5 10
d 1 f 2 314 9 13 4 8 5 1210 7 6 11
f 14 13 8 12 7 6 11
Ord. Topológica A B D G C E F
Ord. Topológica A B D G C E F
IAED, 2014/2015
Grupo IV (1.5+1.5 = 3.0 val.)
IV.a) Suponha que lhe éGrupo IV implementar
pedido para (1.5+1.5 = uma3.0 val.) de dados de suporte à
estrutura
gestão da rede social de estudantes do IST. Sabendo que esta rede se trata de um grafo
IV.a) Suponha que lhe é pedido para implementar uma
esparso, indique qual a representação de grafos que escolheria. Indique também a expressão
gestão
da complexidade assimptótica maisda rede social
apertada de estudantes
para o espaço do essa
necessário para IST.estrutura
Sabendo de que
dados em termos do númeroesparso,
vérticesindique qual aderepresentação
n e do número arcos m. de grafos que escolhe
da complexidade assimptótica mais apertada para o espaço
Solução: Lista de adjacências com O(n + m) espaço.
dados em termos do número vértices n e do número de arco
IAED, 2014/2015
IV.c) Considere as seguintes afirmações, relativas a um grafo dirigido G = (V, E), com |V | vértices
e |E| arcos. Indique se cada uma das afirmações é verdadeira (V) ou falsa (F). Cada resposta errada
desconta uma resposta certa. A cotação mı́nima que é possı́vel obter nesta pergunta é 0.
Solução:
1. F
2. V
3. F
4. F
IAED, 2014/2015
Indique as expressões erradas:
F A
C E
B D
IAED, 2014/2015