Carregar apresentação
A apresentação está carregando. Por favor, espere
PublicouAna Beatriz Bardini Barreto Alterado mais de 8 anos atrás
1
Programação de algoritmos Rodrigo Reis Gomes Bacharel em Informática – UFRJ – 1999 Mestre em Modelagem Computacional – UERJ – 2003 Doutor em Modelagem Computacional – UERJ – 2012 rodrigoreisgomes@gmail.com
2
Algoritmos e Estruturas de Dados I Rodrigo Reis Gomes Bacharel em Informática – UFRJ – 1999 Mestre em Modelagem Computacional – UERJ – 2003 Doutor em Modelagem Computacional – UERJ – 2012 rodrigoreisgomes@gmail.com
3
Ementa Complexidade de algoritmos Alocação sequencial Alocação encadeada Algoritmos de ordenação Introdução a árvores
4
Bibliografia Eslaides: www.infocefetnf.pro.br/rodrigoreisgomes/ Bibliografia básica: 1. SZWARCFITER, Jayme Luiz; MARKENZON, Lilian. Estrutura de dados e seus algoritmos. 2a Edição. Rio de Janeiro: LTC, 1994. 2. TENENBAUM, Aaron M.; LANGSAM, Yedidyah; AUGENSTEIN, Moshe J. Estrutura de dados usando C. São Paulo: Makron, 2005. 3. FORBELLONE, André Luiz Villar; EBERSPACHHER, Henri Frederico. Lógica de programação: a construção de algoritmos e estruturas de dados. 3ª Edição. São Paulo: Pearson Education do Brasil, 2010. Bibliografia complementar: 1. GUIMARÃES, Angelo de Moura; LAGES, Newton Alberto de Castilho. Algoritmos e Estruturas de Dados. Rio de Janeiro: LTC, 1994. 2. EDELWEISS, Nina; GALANTE, Renata. Estruturas de Dados. Porto Alegre: Bookman, 2009. 3. PEREIRA, Silvio do Lago. Estrutura de dados fundamentais : conceitos e aplicações. 12.ed. rev. e ampl. São Paulo: Érica, 2008. 4. VELOSO, Paulo A. S. Estruturas de dados. Rio de Janeiro: Elsevier: Campus, c1983. 5. TOSCANI, Laira V.; VELOSO, Paulo A. S. Complexidade de algoritmos: análise, projeto e métodos. 3.ed. Porto Alegre: Bookman, 2012.
5
Complexidade de algoritmos Característica importante de um algoritmo Tempo de execução Formas de determinação do tempo de execução Métodos empíricos Métodos analíticos
6
Complexidade de algoritmos Métodos empíricos X analíticos Métodos empíricos Executar o algoritmos para diversas entradas Depende do computador, da LP e do compilador Métodos analíticos Visam a obtenção de uma ordem de grandeza para o tempo de execução Uma expressão matemática traduz o comportamento de tempo de execução do algoritmo
7
Complexidade de algoritmos Métodos analíticos Obter uma expressão matemática para avaliar o tempo de execução de um algoritmo não é simples Simplificações introduzidas: Só serão considerados algoritmos cujas entradas consistam em uma quantidade suficientemente grande Não serão consideradas constantes aditivas ou multiplicativas na expressão resultante O tempo de execução será aproximado e expresso em função da entrada
8
Complexidade de algoritmos Métodos analíticos Um algoritmo é dividido em passos Cada passo consiste na execução de um número fixo de operações básicas O tempo de execução de cada operação básica é considerado constante A operação básica de maior frequência de execução será chamada de operação dominante O número de passos pode ser interpretado como o número de execuções da operação de maior frequência
9
Complexidade de algoritmos Métodos analíticos Exemplo: inversão de uma sequência Cada passo corresponde à troca de posição entre dois elementos da sequência de tamanho n O número de passos é igual ao número de execuções do bloco for (n / 2) for (i = 0; i < n/2; i = i+1) { temp = S[i]; S[i] = S[n-i-1]; S[n-i-1] = temp; }
10
Complexidade de algoritmos Métodos analíticos Exemplo: soma de matrizes quadradas Cada passo corresponde à soma de um elemento de a por um elemento de b O número de passos é igual ao número de somas efetuadas (n 2 ) for (i = 0; i < n; i = i+1) for (j = 0; j < n; j = j+1) c[i][j] = a[i][j] + b[i][j];
11
Complexidade de algoritmos Métodos analíticos Exemplo: produto de matrizes quadradas Cada passo corresponde ao produto de um elemento de a por um elemento de b O número de passos é igual ao número de produtos efetuados (n 3 ) for (i = 0; i < n; i = i+1) for (j = 0; j < n; j = j+1) { c[i][j] = 0; for (k = 0; k < n; j = k+1) c[i][j] = c[i][j] + a[i][k] * b[k][j]; }
12
Complexidade de algoritmos Complexidade de tempo Complexidade do pior caso Número de passos que o algoritmo executa para a entrada mais desfavorável É a mais importante Oferece um limite superior para a quantidade de passos Complexidade do melhor caso Utilizada em casos específicos Complexidade do caso médio Exige o prévio conhecimento da função de probabilidades das diferentes entradas Em diversos casos, essa distribuição é desconhecida
13
Complexidade de algoritmos Complexidade de tempo Complexidade do pior caso Número de passos que o algoritmo executa para a entrada mais desfavorável É a mais importante Oferece um limite superior para a quantidade de passos Complexidade do melhor caso Utilizada em casos específicos Complexidade do caso médio Exige o prévio conhecimento da função de probabilidades das diferentes entradas Em diversos casos, essa distribuição é desconhecida O termo complexidade será empregado com o significado de complexidade do pior caso
14
Complexidade de algoritmos A notação O Utilizada para exprimir complexidades Despreza constantes aditivas ou multiplicativas Aplicada a entradas suficientemente grandes Atua como uma aproximação para a quantidade de passos Número de passosAproximação 3nO(n) n 2 + nO(n 2 ) 6n 3 + 4n - 9O(n 3 )
15
Complexidade de algoritmos A notação O Propriedades O(g + h) = O(g) + O(h) O(k x g) = kO(g) = O(g) Número de passosAproximação n 2 - 1O(n 2 ) n 3 - 1O(n 3 ) 403O(1) 5 + 2log(n) + 3log 2 nO(log 2 n) n + 2log(n) + 3log 2 nO(n) 3n + 5log(n) + 2O(n) 5x2 n + 5n 10 O(2 n ) g, h: funções reais k: constante
16
Complexidade de algoritmos A notação O Exemplo: inversão de uma sequência O número de passos é igual ao número de execuções do bloco for (n / 2) A complexidade é dada por O(n) for (i = 0; i < n/2; i = i+1) { temp = S[i]; S[i] = S[n-i-1]; S[n-i-1] = temp; }
17
Complexidade de algoritmos A notação O Exemplo: fatorial O número de passos é igual ao número de produtos efetuados (n) A complexidade é dada por O(n) fat = 1; for (i = 1; i <= n; i = i+1) fat = fat * i;
18
Complexidade de algoritmos Algoritmos recursivos Algoritmo que contém, em sua descrição, uma ou mais chamadas a si mesmo Em determinadas situações, a recursividade é a solução mais simples Exemplo clássico: fatorial Outro exemplo: as torres de hanói int fat(int n) { if (n <= 1) return 1; else return n*fat(n-1); }
19
Complexidade de algoritmos As torres de Hanói Três pinos (A, B, C), denominados origem, destino e trabalho n discos de diâmetros diferentes Inicialmente, todos os discos encontram-se no pino origem, em ordem decrescente de tamanho, de baixo para cima O objetivo é empilhar todos os discos no pino destino Um único disco pode ser movido por vez Nenhum disco pode ser colocado sobre outro de tamanho menor
20
Complexidade de algoritmos As torres de Hanói Três pinos (A, B, C), denominados origem, destino e trabalho n discos de diâmetros diferentes Inicialmente, todos os discos encontram-se no pino origem, em ordem decrescente de tamanho, de baixo para cima O objetivo é empilhar todos os discos no pino destino Um único pino pode ser movido por vez Nenhum disco pode ser colocado sobre outro de tamanho menor
21
Complexidade de algoritmos As torres de Hanói void hanoi(int n, int A, int B, int C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); }
22
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); }
23
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); }
24
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); }
25
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); }
26
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } mover(A, B);
27
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } mover(A, B);
28
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } mover(A, B); mover(A, C);
29
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, A); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } mover(A, B); mover(A, C);
30
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, A); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } mover(A, B); mover(A, C);
31
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } mover(A, B); mover(A, C); mover(B, C);
32
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } mover(A, B); mover(A, C); mover(B, C);
33
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } mover(A, B); mover(A, C); mover(B, C); mover(A, B);
34
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(2, C, B, A) { hanoi(1, C, A, B); mover(C, B); hanoi(1, A, B, C); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } mover(A, B); mover(A, C); mover(B, C); mover(A, B);
35
Complexidade de algoritmos As torres de Hanói mover(A, B); mover(A, C); mover(B, C); mover(A, B); void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(2, C, B, A) { hanoi(1, C, A, B); mover(C, B); hanoi(1, A, B, C); } void hanoi(1, C, A, B) { hanoi(0, C, B, A); mover(C, A); hanoi(0, B, A, C); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); }
36
Complexidade de algoritmos As torres de Hanói mover(A, B); mover(A, C); mover(B, C); mover(A, B); void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(2, C, B, A) { hanoi(1, C, A, B); mover(C, B); hanoi(1, A, B, C); } void hanoi(1, C, A, B) { hanoi(0, C, B, A); mover(C, A); hanoi(0, B, A, C); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); }
37
Complexidade de algoritmos As torres de Hanói mover(A, B); mover(A, C); mover(B, C); mover(A, B); mover(C, A); void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(2, C, B, A) { hanoi(1, C, A, B); mover(C, B); hanoi(1, A, B, C); } void hanoi(1, C, A, B) { hanoi(0, C, B, A); mover(C, A); hanoi(0, B, A, C); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); }
38
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(2, C, B, A) { hanoi(1, C, A, B); mover(C, B); hanoi(1, A, B, C); } void hanoi(1, C, A, B) { hanoi(0, C, B, A); mover(C, A); hanoi(0, B, A, C); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } mover(A, B); mover(A, C); mover(B, C); mover(A, B); mover(C, A);
39
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(2, C, B, A) { hanoi(1, C, A, B); mover(C, B); hanoi(1, A, B, C); } void hanoi(1, C, A, B) { hanoi(0, C, B, A); mover(C, A); hanoi(0, B, A, C); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } mover(A, B); mover(A, C); mover(B, C); mover(A, B); mover(C, A); mover(C, B);
40
Complexidade de algoritmos As torres de Hanói mover(A, B); mover(A, C); mover(B, C); mover(A, B); mover(C, A); mover(C, B); void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(2, C, B, A) { hanoi(1, C, A, B); mover(C, B); hanoi(1, A, B, C); } void hanoi(1, C, A, B) { hanoi(0, C, B, A); mover(C, A); hanoi(0, B, A, C); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); }
41
Complexidade de algoritmos As torres de Hanói mover(A, B); mover(A, C); mover(B, C); mover(A, B); mover(C, A); mover(C, B); void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(2, C, B, A) { hanoi(1, C, A, B); mover(C, B); hanoi(1, A, B, C); } void hanoi(1, C, A, B) { hanoi(0, C, B, A); mover(C, A); hanoi(0, B, A, C); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); }
42
Complexidade de algoritmos As torres de Hanói mover(A, B); mover(A, C); mover(B, C); mover(A, B); mover(C, A); mover(C, B); mover(A, B); void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(2, C, B, A) { hanoi(1, C, A, B); mover(C, B); hanoi(1, A, B, C); } void hanoi(1, C, A, B) { hanoi(0, C, B, A); mover(C, A); hanoi(0, B, A, C); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); }
43
Complexidade de algoritmos As torres de Hanói mover(A, B); mover(A, C); mover(B, C); mover(A, B); mover(C, A); mover(C, B); mover(A, B); void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(2, C, B, A) { hanoi(1, C, A, B); mover(C, B); hanoi(1, A, B, C); } void hanoi(1, C, A, B) { hanoi(0, C, B, A); mover(C, A); hanoi(0, B, A, C); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); }
44
Complexidade de algoritmos As torres de Hanói mover(A, B); mover(A, C); mover(B, C); mover(A, B); mover(C, A); mover(C, B); mover(A, B);
45
Complexidade de algoritmos Algoritmos recursivos Cálculo da complexidade Determina-se o número de chamadas à recursão Calcula-se a complexidade da execução correspondente a uma única chamada Multiplica-se o número de chamadas pela complexidade da computação de uma chamada isolada
46
Complexidade de algoritmos Algoritmos recursivos Cálculo da complexidade Determina-se o número de chamadas à recursão Calcula-se a complexidade da execução correspondente a uma única chamada Multiplica-se o número de chamadas pela complexidade da computação de uma chamada isolada Qual a complexidade do algoritmo que resolve o problema das torres de Hanói?
47
Complexidade de algoritmos As torres de Hanói void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } N = 11 chamada
48
Complexidade de algoritmos As torres de Hanói void hanoi(2, A, B, C) { hanoi(1, A, C, B); mover(A, B); hanoi(1, C, B, A); } void hanoi(1, A, C, B) { hanoi(0, A, B, C); mover(A, C); hanoi(0, B, C, A); } void hanoi(1, C, B, A) { hanoi(0, C, A, B); mover(C, B); hanoi(0, A, B, C); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } N = 11 chamada N = 23 chamadas
49
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(2, C, B, A) { hanoi(1, C, A, B); mover(C, B); hanoi(1, A, B, C); } void hanoi(1, C, A, B) { hanoi(0, C, B, A); mover(C, A); hanoi(0, B, A, C); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } N = 11 chamada N = 23 chamadas N = 37 chamadas
50
Complexidade de algoritmos As torres de Hanói void hanoi(3, A, B, C) { hanoi(2, A, C, B); mover(A, B); hanoi(2, C, B, A); } void hanoi(2, A, C, B) { hanoi(1, A, B, C); mover(A, C); hanoi(1, B, C, A); } void hanoi(2, C, B, A) { hanoi(1, C, A, B); mover(C, B); hanoi(1, A, B, C); } void hanoi(1, C, A, B) { hanoi(0, C, B, A); mover(C, A); hanoi(0, B, A, C); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(1, B, C, A) { hanoi(0, B, A, C); mover(B, C); hanoi(0, A, C, B); } void hanoi(1, A, B, C) { hanoi(0, A, C, B); mover(A, B); hanoi(0, C, B, A); } void hanoi(n, A, B, C) { if (n>0) { hanoi(n-1, A, C, B); mover(A, B); hanoi(n-1, C, B, A); } N = 11 chamada N = 23 chamadas N = 37 chamadas... N = n? chamadas
51
Complexidade de algoritmos Primeira lista de exercícios
52
Programação de algoritmos Rodrigo Reis Gomes Bacharel em Informática – UFRJ – 1999 Mestre em Modelagem Computacional – UERJ – 2003 Doutor em Modelagem Computacional – UERJ – 2012 rodrigoreisgomes@gmail.com
53
Alocação sequencial Motivação: listas de números inteiros Como implementar? int lista[?]; 10, 50, 1.000.000 ???
54
Alocação sequencial Motivação: listas de números inteiros Como implementar? int * lista; Exemplo para N = 5: Como saber se uma célula está “vazia”? int N, *lista; printf("Tamanho da lista: "); scanf("%d", &N); lista = (int *)malloc(sizeof(int[N])); 1510 0200 lista
55
Alocação sequencial Motivação: listas de números inteiros Como implementar? int ** lista; Exemplo para N = 5: int N, **lista; printf("Tamanho da lista: "); scanf("%d", &N); lista = (int **)malloc(sizeof(int*[N])); lista 15 10 0 -1 NULL
56
Alocação sequencial Motivação: listas de números inteiros Operações a serem construídas: void criarLista (int ** l, int n); int elementosNaLista(int ** l, int n); int buscarNaLista (int ** l, int n, int x); int inserirNaLista (int ** l, int n, int x); int excluirDaLista (int ** l, int n, int x);
57
Alocação sequencial Motivação: listas de números inteiros Criação da lista: void criarLista(int **l, int n) { int i; for(i=0; i < n; i = i+1) l[i] = NULL; }
58
Alocação sequencial Motivação: listas de números inteiros Quantidade de elementos na lista: int elementosNaLista(int ** l, int n) { int i; for(i=0; i < n; i = i+1) if (l[i] == NULL) break; return i; }
59
Alocação sequencial Motivação: listas de números inteiros Busca na lista: int buscarNaLista(int ** l, int n, int x) { int i, busca; busca = -1; //flag para erro for (i=0; i < n; i = i+1) { if (l[i] == NULL) i = n; else if (*(l[i]) == x) { busca = i; i = n; } return busca; }
60
Alocação sequencial Motivação: listas de números inteiros Inserção na lista: int inserirNaLista(int ** l, int n, int x) { int i, M; M = elementosNaLista(l,n); if (M<n) if (buscarNaLista(l, n, x) == -1) { l[M] = &x; return 1; } else return 0; //Elemento já existe else return -1; //Overflow }
61
Alocação sequencial Motivação: listas de números inteiros Exclusão da lista: int excluirDaLista(int ** l, int n, int x) { int i, indice, M; M = elementosNaLista(l,n); if (M != 0) { indice = buscarNaLista(l, n, x); if (indice != -1) { if (indice == n-1) l[indice] = NULL; else for (i = indice; i < M; i = i+1) l[i] = l[i+1]; return 1; } else return 0; //Elemento não existe } else return -1; //Underflow }
62
Alocação sequencial Segunda lista de exercícios
63
Programação de algoritmos Rodrigo Reis Gomes Bacharel em Informática – UFRJ – 1999 Mestre em Modelagem Computacional – UERJ – 2003 Doutor em Modelagem Computacional – UERJ – 2012 rodrigoreisgomes@gmail.com
64
Alocação sequencial Pilhas e filas Pilhas LIFO (Last In First Out) Exemplo do cotidiano: Pilha de rascunhos Filas FIFO (First In First Out) Exemplo do cotidiano: Fila de cinema
65
Alocação sequencial Pilhas Se a pilha não estiver vazia, sempre retiramos o elemento do topo da pilha É necessário ter uma informação sobre onde se localiza o topo da pilha
66
Alocação sequencial Pilhas de números inteiros Como implementar? Exemplo para N = 5: int N; struct TPilha pilha; printf("Tamanho da pilha: "); scanf("%d", &N); struct TPilha { int m; //tamanho int t; //topo int * v; //valores } pilha = 1510 0200 v t = ? m = 5
67
Alocação sequencial Pilhas de números inteiros Operações a serem construídas: void criarPilha (struct TPilha *p, int n); int elementosNaPilha(struct TPilha p); int buscarNaPilha (struct TPilha p, int x); int inserirNaPilha (struct TPilha *p, int x); int excluirDaPilha (struct TPilha *p); void eliminarPilha (struct TPilha *p); p é a pilha n é o tamanho da pilha x é um valor e ser buscado ou inserido na pilha
68
Alocação sequencial Pilhas de números inteiros Criação da pilha: Exemplo para n = 5 void criarPilha(struct TPilha *p, int n) { (*p).m = n; (*p).t = -1; (*p).v = (int *)malloc(sizeof(int[n])); } p = ????? v t = -1 m = 5
69
Alocação sequencial Pilhas de números inteiros Quantidade de elementos na pilha: int elementosNaPilha(struct TPilha p) { return p.t + 1; }
70
Alocação sequencial Pilhas de números inteiros Busca na pilha: int buscarNaPilha(struct TPilha p, int x) { int i, busca; busca = -1; //flag para erro for (i=0; i <= p.t; i = i + 1) if (p.v[i] == x) { busca = i; i = p.t + 1; } return busca; }
71
Alocação sequencial Pilhas de números inteiros Inserção na pilha: int inserirNaPilha(struct TPilha *p, int x) { int i, M; M = elementosNaPilha(*p); if (M < (*p).m) if (buscarNaPilha(*p, x) == -1) { (*p).t = (*p).t + 1; (*p).v[(*p).t] = x; return 1; } else return 0; //Elemento já existe else return -1; //Overflow }
72
Alocação sequencial Pilhas de números inteiros Exclusão da pilha: int excluirDaPilha(struct TPilha *p) { int i, M; M = elementosNaPilha(*p); if (M > 0) { (*p).t = (*p).t - 1; return 1; } else return -1; //Underflow }
73
Alocação sequencial Pilhas de números inteiros Eliminação da pilha: void eliminarPilha(struct TPilha *p) { (*p).m = 0; (*p).t = -1; free((*p).v); }
74
Alocação sequencial Filas Se a fila não estiver vazia, sempre retiramos o elemento do início (f) da fila É necessário ter uma informação sobre onde se localiza o início (f) da fila e outra sobre onde se localiza a retaguarda (r) fila
75
Alocação sequencial Continuação da segunda lista de exercícios
76
Programação de algoritmos Rodrigo Reis Gomes Bacharel em Informática – UFRJ – 1999 Mestre em Modelagem Computacional – UERJ – 2003 Doutor em Modelagem Computacional – UERJ – 2012 rodrigoreisgomes@gmail.com
77
Alocação encadeada Registros dinâmicos Nós de armazenamento são alocados mediante necessidade Ponteiros fazem: O encadeamento dos nós A sinalização de fim dos nós
78
Alocação encadeada Registros dinâmicos Nós de armazenamento são alocados mediante necessidade Ponteiros fazem: O encadeamento dos nós A sinalização de fim dos nós É fundamental utilizar um ponteiro para indicar o início da lista
79
Alocação encadeada Registros dinâmicos Nós de armazenamento são alocados mediante necessidade Ponteiros fazem: O encadeamento dos nós A sinalização de fim dos nós É fundamental utilizar um ponteiro para indicar o início da lista Exemplos: Listas, Filas e Pilhas
80
Alocação encadeada Listas encadeadas Lista de caracteres Representação de cada nó da lista struct TNoDeCaractere { char caractere; struct TNoDeCaractere * proximo; };
81
Alocação encadeada Listas encadeadas Lista de caracteres Representação de cada nó da lista Representação do ponteiro para o início da lista (inicialmente vazia) struct TNoDeCaractere { char caractere; struct TNoDeCaractere * proximo; }; struct TNoDeCaractere * inicio; main() {... inicio = NULL;... }
82
Alocação encadeada Listas encadeadas Lista de caracteres Representação de cada nó da lista Representação do ponteiro para o início da lista (inicialmente vazia) struct TNoDeCaractere { char caractere; struct TNoDeCaractere * proximo; }; struct TNoDeCaractere * inicio; main() {... inicio = NULL;... } “NULL” faz um ponteiro apontar para nenhuma posição de memória. O ponteiro fica aterrado.
83
Alocação encadeada Listas encadeadas (criação de novo nó) 01 void armazenar (char valor) 02 { 03 struct TNoDeCaractere *p, *np; 04 //Se a lista está vazia, cria um nó e faz "inicio" apontar para ele. 05 if (inicio == NULL) 06 { 07 np = malloc(sizeof(struct TNoDeCaractere)); 08 (*np).caractere = valor; 09 (*np).proximo = NULL; 10 inicio = np; 11 } 12 else //Caso contrário, ou seja, se a lista não está vazia... 13 { 14 p = inicio; 15 //varre toda a lista, 16 while ((*p).proximo != NULL) 17 p = (*p).proximo; 18 //cria o novo nó 19 np = malloc(sizeof(struct TNoDeCaractere)); 20 (*np).caractere = valor; 21 (*np).proximo = NULL; 22 //e liga a lista existente ao novo nó. 23 (*p).proximo = np; 24 } 25 }
84
Alocação encadeada Listas encadeadas (criação de novo nó) Em uma lista vazia Estrutura inicial:
85
Alocação encadeada Listas encadeadas (criação de novo nó) Em uma lista vazia Estrutura inicial: Alocação do novo nó: 07 np = malloc(sizeof(struct TNoDeCaractere)); malloc – reserva um novo espaço de memória (sizeof(struct TNoDeCaractere)) – do tamanho exato de um registro “TNoDeCaractere”, np = – e faz este espaço ser apontado por “np”.
86
Alocação encadeada Listas encadeadas (criação de novo nó) Em uma lista vazia Estrutura inicial: Alocação do novo nó: Nova estrutura: 07 np = malloc(sizeof(struct TNoDeCaractere)); malloc – reserva um novo espaço de memória (sizeof(struct TNoDeCaractere)) – do tamanho exato de um registro “TNoDeCaractere”, np = – e faz este espaço ser apontado por “np”.
87
Alocação encadeada Listas encadeadas (criação de novo nó) Em uma lista vazia Estrutura atual:
88
Alocação encadeada Listas encadeadas (criação de novo nó) Em uma lista vazia Estrutura atual: Armazenamento do valor ‘O’ no novo nó e aterramento do novo nó: 08 (*np).caractere = valor; //supor que " valor" seja 'O' 09 (*np).proximo = NULL;
89
Alocação encadeada Listas encadeadas (criação de novo nó) Em uma lista vazia Estrutura atual: Armazenamento do valor ‘O’ no novo nó e aterramento do novo nó: Nova estrutura: 08 (*np).caractere = valor; //supor que " valor" seja 'O' 09 (*np).proximo = NULL;
90
Alocação encadeada Listas encadeadas (criação de novo nó) Em uma lista vazia Estrutura atual:
91
Alocação encadeada Listas encadeadas (criação de novo nó) Em uma lista vazia Estrutura atual: Atualização do ponteiro para o início da lista: 10 inicio = np;
92
Alocação encadeada Listas encadeadas (criação de novo nó) Em uma lista vazia Estrutura atual: Atualização do ponteiro para o início da lista: Nova estrutura: 10 inicio = np;
93
Alocação encadeada Listas encadeadas (criação de novo nó) Em uma lista vazia Estrutura atual: Atualização do ponteiro para o início da lista: Nova estrutura: 10 inicio = np; No encerramento do procedimento, a variável “np” é excluída da memória, pois ela é uma variável local ao procedimento.
94
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual:
95
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual: Atribuição de valor inicial ao ponteiro p: 14 p = inicio;
96
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual: Atribuição de valor inicial ao ponteiro p: Nova estrutura: 14 p = inicio;
97
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual:
98
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual: Varredura de toda a lista: 16 while ((*p).proximo != NULL) 17 p = (*p).proximo; ppp p
99
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual: Varredura de toda a lista: 16 while ((*p).proximo != NULL) 17 p = (*p).proximo; ppp p Como o campo próximo do nó apontado por p já é o fim da fila, a linha 17 não é executada nenhuma vez.
100
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual:
101
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual: Alocação do novo nó: 19 np = malloc(sizeof(struct TNoDeCaractere));
102
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual: Alocação do novo nó: Nova estrutura: 19 np = malloc(sizeof(struct TNoDeCaractere));
103
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual:
104
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual: Armazenamento do valor ‘I’ no novo nó e aterramento do novo nó: 20 (*np).caractere = valor; //supor que " valor" seja 'I' 21 (*np).proximo = NULL;
105
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual: Armazenamento do valor ‘I’ no novo nó e aterramento do novo nó: Nova estrutura: 20 (*np).caractere = valor; //supor que " valor" seja 'I' 21 (*np).proximo = NULL;
106
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual:
107
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual: Atualização do ponteiro para o início da lista: 23 (*p).proximo = np;
108
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual: Atualização do ponteiro para o início da lista: Nova estrutura: 23 (*p).proximo = np;
109
Alocação encadeada Listas encadeadas (criação de novo nó) No final de uma lista Estrutura atual: Atualização do ponteiro para o início da lista: Nova estrutura: 23 (*p).proximo = np; No encerramento do procedimento, as variáveis ”p” e “np” são excluídas da memória, pois elas são variáveis locais ao procedimento.
110
Alocação encadeada Listas encadeadas (exclusão de um nó) 01 void retirar (char valor) 02 { 03 struct TNoDeCaractere * pAnt, *p; 04 //Verifica se a partir do segundo nó, há nó a ser retirado. 05 pAnt = inicio; 06 p = (*inicio).proximo; 07 while (p != NULL) 08 { 09 if ((*p).caractere == valor) 10 { 11 (*pAnt).proximo = (*p).proximo; 12 free(p); 13 p = (*pAnt).proximo; 14 } 15 else { 16 pAnt = (*pAnt).proximo; 17 p = (*p).proximo; 18 } 19 } 20 //Testa se a lista está com o valor a ser retirado no primeiro nó. 21 if ((*inicio).caractere == valor) 22 { 23 p = (*inicio).proximo; 24 free(inicio); 25 inicio = p; 26 } 27 }
111
Alocação encadeada Listas encadeadas (exclusão do primeiro nó) Estrutura atual:
112
Alocação encadeada Listas encadeadas (exclusão do primeiro nó) Estrutura atual: Atualização do ponteiro para o início da lista: 23 p = (*inicio).proximo;
113
Alocação encadeada Listas encadeadas (exclusão do primeiro nó) Estrutura atual: Atualização do ponteiro para o início da lista: Nova estrutura: 23 p = (*inicio).proximo;
114
Alocação encadeada Listas encadeadas (exclusão do primeiro nó) Estrutura atual:
115
Alocação encadeada Listas encadeadas (exclusão do primeiro nó) Estrutura atual: Exclusão do nó: 24 free(inicio); Libere a área de memória apontada por “inicio”.
116
Alocação encadeada Listas encadeadas (exclusão do primeiro nó) Estrutura atual: Exclusão do nó: Nova estrutura: 24 free(inicio); Libere a área de memória apontada por “inicio”.
117
Alocação encadeada Listas encadeadas (exclusão do primeiro nó) Estrutura atual:
118
Alocação encadeada Listas encadeadas (exclusão do primeiro nó) Estrutura atual: Atualização do ponteiro para o início da lista: 25 inicio = p;
119
Alocação encadeada Listas encadeadas (exclusão do primeiro nó) Estrutura atual: Atualização do ponteiro para o início da lista: Nova estrutura: 25 inicio = p;
120
Alocação encadeada Listas encadeadas (exclusão do primeiro nó) Estrutura atual: Atualização do ponteiro para o início da lista: Nova estrutura: 25 inicio = p; No encerramento do procedimento, a variável “p” é excluída da memória, pois ela é uma variável local ao procedimento.
121
Alocação encadeada Listas encadeadas (exclusão de nó genérico) Varredura para achar o elemento a ser excluído: 05 pAnt = inicio; 06 p = (*inicio).proximo; 07 while (p != NULL) 08 { 09 if ((*p).caractere == valor) 10 { 11 (*pAnt).proximo = (*p).proximo; 12 free(p); 13 p = (*pAnt).proximo; 14 } 15 else { 16 pAnt = (*pAnt).proximo; 17 p = (*p).proximo; 18 } 19 } p pAnt
122
Alocação encadeada Listas encadeadas (exclusão de nó genérico) Estrutura atual: pAnt p
123
Alocação encadeada Listas encadeadas (exclusão de nó genérico) Estrutura atual: Exclusão do elemento e redistribuição da lista: 11 (*pAnt).proximo = (*p).proximo; 12 free(p); 13 p = (*pAnt).proximo; pAnt p
124
Alocação encadeada Listas encadeadas (exclusão de nó genérico) Estrutura atual: Exclusão do elemento e redistribuição da lista: 11 (*pAnt).proximo = (*p).proximo; 12 free(p); 13 p = (*pAnt).proximo; pAnt p No encerramento do procedimento, as variáveis “p” e “pAnt” são excluídas da memória, pois elas são variáveis locais ao procedimento.
125
Alocação encadeada Filas (FIFO – First In, First Out) O primeiro a entrar é o primeiro a sair Como uma fila de cinema Exemplo:
126
Alocação encadeada Filas (FIFO – First In, First Out) O primeiro a entrar é o primeiro a sair Como uma fila de cinema Exemplo:
127
Alocação encadeada Filas (FIFO – First In, First Out) O primeiro a entrar é o primeiro a sair Como uma fila de cinema Exemplo: No momento, o elemento a ser retirado é o nó que contém o número 3!
128
Alocação encadeada Pilhas (LIFO – Last In, First Out) O último a entrar é o primeiro a sair Como uma pilha de rascunhos Exemplo:
129
Alocação encadeada Pilhas (LIFO – Last In, First Out) O último a entrar é o primeiro a sair Como uma pilha de rascunhos Exemplo:
130
Alocação encadeada Pilhas (LIFO – Last In, First Out) O último a entrar é o primeiro a sair Como uma pilha de rascunhos Exemplo: O elemento a ser retirado é o nó que contém o número 7!
131
Alocação encadeada Terceira lista de exercícios
132
Alocação encadeada Listas circulares O último elemento tem uma ligação para o primeiro elemento da lista, formando um ciclo Útil quando não há ordenação na lista A rigor não existe “primeiro” ou “último” Ainda é necessário que exista um ponteiro para algum elemento, para a localização da lista por convenção, referência do “primeiro” ou do “último”
133
Alocação encadeada Listas circulares O último elemento tem uma ligação para o primeiro elemento da lista, formando um ciclo Útil quando não há ordenação na lista A rigor não existe “primeiro” ou “último” Ainda é necessário que exista um ponteiro para algum elemento, para a localização da lista por convenção, referência do “primeiro” ou do “último”
134
Alocação encadeada Listas duplamente encadeadas Útil quando é preciso percorrer a lista na ordem inversa Remoção de um elemento não precisa guardar anterior Um conjunto maior de ligações precisam ser atualizadas
135
Alocação encadeada Listas duplamente encadeadas Útil quando é preciso percorrer a lista na ordem inversa Remoção de um elemento não precisa guardar anterior Um conjunto maior de ligações precisam ser atualizadas
136
Alocação encadeada Terceira lista de exercícios (continuação)
137
Programação de algoritmos Rodrigo Reis Gomes Bacharel em Informática – UFRJ – 1999 Mestre em Modelagem Computacional – UERJ – 2003 Doutor em Modelagem Computacional – UERJ – 2012 rodrigoreisgomes@gmail.com
138
Algoritmos de ordenação Método da bolha (bubble sort)
139
Algoritmos de ordenação Método da bolha (bubble sort) No final da primeira iteração, o último elemento é certamente o maior.
140
Algoritmos de ordenação Método da bolha (bubble sort) No final da primeira iteração, o último elemento é certamente o maior. No final da segunda iteração, o penúltimo elemento é certamente o maior.
141
Algoritmos de ordenação Método da bolha (bubble sort) No final da primeira iteração, o último elemento é certamente o maior. No final da segunda iteração, o penúltimo elemento é certamente o maior. E assim, sucessivamente...
142
Algoritmos de ordenação Método da bolha (bubble sort) No final da primeira iteração, o último elemento é certamente o maior. No final da segunda iteração, o penúltimo elemento é certamente o maior. E assim, sucessivamente... É como se uma BOLHA carregasse o maior elemento para frente.
143
Algoritmos de ordenação Ordenação por partição (quick sort) 1. Eleja um pivô. 2. Rearranje a lista: os elementos anteriores ao pivô devem ser menores que ele; os elementos posteriores ao pivot devem ser maiores que ele. Ao fim do processo, o pivô estará em sua posição final e haverá duas sublistas não ordenadas. 3. Recursivamente, ordene a duas sublistas.
144
Algoritmos de ordenação Ordenação por intercalação (merge sort) Divida a lista original pela metade até que as listas geradas tenham tamanho igual a 1. Em seguida, repita: 1. ordene a primeira metade recursivamente 2. ordene a segunda metade recursivamente 3. intercale as duas metades, ordenadamente Até gerar uma lista do mesmo tamanho da original.
145
Algoritmos de ordenação Ordenação por intercalação (merge sort) mergeSort(v, tam) = mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)
146
Algoritmos de ordenação Ordenação por intercalação (merge sort) v = {38, 27, 43, 3, 9, 82, 10} mergeSort(v, 7) mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)
147
Algoritmos de ordenação Ordenação por intercalação (merge sort) v = {38, 27, 43, 3, 9, 82, 10} mergeSort(v, 7) mergeSort(v, 3) mergeSort(v+3, 4) ordenar(v, 7) mergeSort(v, 1) mergeSort(v+1, 2) ordenar(v, 3) 38 mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)
148
Algoritmos de ordenação Ordenação por intercalação (merge sort) v = {38, 27, 43, 3, 9, 82, 10} mergeSort(v, 7) mergeSort(v, 3) mergeSort(v+3, 4) ordenar(v, 7) mergeSort(v, 1) mergeSort(v+1, 2) ordenar(v, 3) mergeSort(v+1, 1) mergeSort(v+2, 1) ordenar(v+1, 2) 27 38 43 mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)
149
Algoritmos de ordenação Ordenação por intercalação (merge sort) v = {38, 27, 43, 3, 9, 82, 10} mergeSort(v, 7) mergeSort(v, 3) mergeSort(v+3, 4) ordenar(v, 7) mergeSort(v, 1) mergeSort(v+1, 2) ordenar(v, 3) mergeSort(v+1, 1) mergeSort(v+2, 1) ordenar(v+1, 2) 27 38 43 3827 43 2738 43 mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)
150
Algoritmos de ordenação Ordenação por intercalação (merge sort) v = {38, 27, 43, 3, 9, 82, 10} mergeSort(v, 7) mergeSort(v, 3) mergeSort(v+3, 4) ordenar(v, 7) mergeSort(v, 1) mergeSort(v+1, 2) ordenar(v, 3) mergeSort(v+3, 2) mergeSort(v+5, 2) ordenar(v+3, 4) mergeSort(v+1, 1) mergeSort(v+2, 1) ordenar(v+1, 2) 27 38 43 3827 43 2738 43 mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)
151
Algoritmos de ordenação Ordenação por intercalação (merge sort) v = {38, 27, 43, 3, 9, 82, 10} mergeSort(v, 7) mergeSort(v, 3) mergeSort(v+3, 4) ordenar(v, 7) mergeSort(v, 1) mergeSort(v+1, 2) ordenar(v, 3) mergeSort(v+3, 1) mergeSort(v+4, 1) ordenar(v+3, 2) mergeSort(v+3, 2) mergeSort(v+5, 2) ordenar(v+3, 4) mergeSort(v+1, 1) mergeSort(v+2, 1) ordenar(v+1, 2) 27 38 43 3827 43 2738 43 0903 mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)
152
Algoritmos de ordenação Ordenação por intercalação (merge sort) v = {38, 27, 43, 3, 9, 82, 10} mergeSort(v, 7) mergeSort(v, 3) mergeSort(v+3, 4) ordenar(v, 7) mergeSort(v, 1) mergeSort(v+1, 2) ordenar(v, 3) mergeSort(v+3, 1) mergeSort(v+4, 1) ordenar(v+3, 2) mergeSort(v+3, 2) mergeSort(v+5, 2) ordenar(v+3, 4) mergeSort(v+1, 1) mergeSort(v+2, 1) ordenar(v+1, 2) mergeSort(v+5, 1) mergeSort(v+6, 1) ordenar(v+5, 2) 27 8210 82 38 43 3827 43 2738 43 0903 mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)
153
Algoritmos de ordenação Ordenação por intercalação (merge sort) v = {38, 27, 43, 3, 9, 82, 10} mergeSort(v, 7) mergeSort(v, 3) mergeSort(v+3, 4) ordenar(v, 7) mergeSort(v, 1) mergeSort(v+1, 2) ordenar(v, 3) mergeSort(v+3, 1) mergeSort(v+4, 1) ordenar(v+3, 2) mergeSort(v+3, 2) mergeSort(v+5, 2) ordenar(v+3, 4) mergeSort(v+1, 1) mergeSort(v+2, 1) ordenar(v+1, 2) mergeSort(v+5, 1) mergeSort(v+6, 1) ordenar(v+5, 2) 27 8210 82 38 43 3827 43 2738 43 0903 0903 1082 mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)
154
Algoritmos de ordenação Ordenação por intercalação (merge sort) v = {38, 27, 43, 3, 9, 82, 10} mergeSort(v, 7) mergeSort(v, 3) mergeSort(v+3, 4) ordenar(v, 7) mergeSort(v, 1) mergeSort(v+1, 2) ordenar(v, 3) mergeSort(v+3, 2) mergeSort(v+5, 2) ordenar(v+3, 4) 10820309 43 3827 43 2738 10820309432738 43822738100309 mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)
155
Algoritmos de ordenação Quarta lista de exercícios
156
Programação de algoritmos Rodrigo Reis Gomes Bacharel em Informática – UFRJ – 1999 Mestre em Modelagem Computacional – UERJ – 2003 Doutor em Modelagem Computacional – UERJ – 2012 rodrigoreisgomes@gmail.com
157
Introdução a árvores Árvore é uma estrutura finita de vértices Um vértice r é a raiz Os demais são as subárvores de r Floresta é um conjunto de árvores
158
Introdução a árvores Útil para representar uma expressão aritmética C Cada operador binário e seu par de operandos correspondem a um nó da árvore e suas duas subárvores
159
Introdução a árvores Conceitos A é raiz da árvore de T D é irmão de X C é tio de X B é pai de X e X é filho de B A é avô de X O número de filhos é o grau de saída de um nó Um nó sem filhos é uma folha Um nó não folha é um nó interior T A BC X DE
160
Introdução a árvores Conceitos Caminho de uma árvore é uma sequência de nós distintos (v 1, v 2, v 3,..., v k-1, v k ) tal que sempre existe entre nós consecutivos (v 1 v 2, v 2 v 3,..., v k-1 v k ) a relação “é filho de” ou “é pai de”. O comprimento do caminho é dado pela quantidade de pares da relação T A BC X DE (AB, BX) é um caminho de comprimento 2.
161
Introdução a árvores Conceitos Nível de um nó v é o número de nós do caminho da raiz até v. A raiz tem nível igual a 1. Altura de um nó v é o número de nós do maior caminho de v até um de seus descendentes. As folhas têm altura igual a 1. Altura da árvore é igual ao nível da raiz. T A BC X DE
162
Introdução a árvores Conceitos Uma árvore ordenada é aquela na qual os filhos de cada nó estão ordenados. Assume-se que tal ordenação se desenvolva da esquerda para a direita. As árvores abaixo são distintas se forem consideradas ordenadas
163
Introdução a árvores Conceitos Árvores não ordenadas são isomorfas quando puderem se tornar coincidentes através de uma permutação na ordem das subárvores de seus nós. Árvores ordenadas são isomorfas quando forem coincidentes, segundo a ordenação de seus nós.
164
Introdução a árvores Conceitos Subárvore (a) de uma árvore é o conjunto de todos os vértices descendentes de um nó v, além do próprio nó v Subárvore parcial (b) de uma árvore é o conjunto de alguns vértices descendentes de um nó v, além de v
165
Introdução a árvores Árvores binárias Cada nó possui no máximo dois filhos: uma subárvore da esquerda e/ou uma subárvore da direita Admite-se árvore binária nula ou unitária
166
Introdução a árvores Árvores binárias a) Estritamente binária: não é possível um nó possuir um único filho b) Completa: a distância entre quaisquer folhas é de, no máximo, 1 nível. c) Cheia: Todos os nós têm dois filhos, exceto as folhas.
167
Introdução a árvores Árvores binárias d) Zigue-zague: Cada nó interior (não folha) possui exatamente um filho
168
Introdução a árvores Armazenamendo de árvores binárias struct TNoDeArvoreBinaria { char info; struct TNoDeArvoreBinaria * esq; struct TNoDeArvoreBinaria * dir; } * raiz;
169
Introdução a árvores Percursos em árvores binárias Percurso em pré-ordem Visitar a raiz Percorrer sua subárvore da esquerda, em pré-ordem Percorrer sua subárvore da direita, em pré-ordem Percurso em ordem simétrica Percorrer sua subárvore da esquerda, em ordem simétrica Visitar a raiz Percorrer sua subárvore da direita, em ordem simétrica Percurso em pré-ordem Visitar a raiz Percorrer sua subárvore da esquerda, em pós-ordem Percorrer sua subárvore da direita, em pós-ordem
170
Introdução a árvores Inclusão em árvores binárias Incluir um nó de tal modo que a subárvore Da esquerda: tenha somente nós com valores menores Da direita: tenha somente nós com valores maiores
171
Introdução a árvores Exclusão em árvores binárias Nó folha: Excluir e fazer o pai passar a apontar para nada
172
Introdução a árvores Exclusão em árvores binárias Nó com filho único: Excluir e fazer o pai apontar para o filho do nó excluído
173
Introdução a árvores Exclusão em árvores binárias Nó com dois filhos: Substituir o valor do nó pelo valor do elemento mais à esquerda da sub-árvore da direita Excluir o elemento e, se ele elemento tinha filho à direita, fazer seu pai apontar para este filho
174
Introdução a árvores Árvores m-árias Generalização da árvore binária Cada nó possui m subárvores Exemplo: Árvores ternárias
175
Introdução a árvores Árvores m-árias Generalização da árvore binária Cada nó possui m subárvores Exemplo: Árvores ternárias Árvore binária de n nós demanda 2n posições de memória para os ponteiros.
176
Introdução a árvores Árvores m-árias Generalização da árvore binária Cada nó possui m subárvores Exemplo: Árvores ternárias Árvore m-ária de n nós demanda mn posições de memória para os ponteiros.
177
Introdução a árvores Conversão de árvore em árvore binária T é uma árvore genérica original T’ é a árvore binária equivalente a T A raiz de T é também a raiz de T’ Para cada nó v de T Se v possui irmão em T, então o irmão mais à esquerda de v em T será o filho à direita de v em T’ Se v possui filho em T, então o filho mais à esquerda de v em T será o filho também à esquerda de v em T’
178
Introdução a árvores Conversão de árvore em árvore binária
179
Introdução a árvores Conversão de uma floresta Supor que as raízes sejam nós irmãos Aplicar o algoritmo de conversão de árvore em árvore binária
180
Introdução a árvores Árvores com costura Uma costura é um ponteiro de um nó para outro nó da árvore Uma costura somente existe em substituição a um ponteiro aterrado Se um ponteiro esquerdo (direito) é nulo, ele passa então a apontar para o antecessor (sucessor) deste nó, segundo algum percurso Dois campos (ecostura e dcostura) booleanos são acrescentados para informar se há uma costura na esquerda ou na direita do nó
181
Introdução a árvores Árvores com costura
182
Introdução a árvores Árvores com costura Percurso em ordem simétrica: D G B A H E I C F
183
Introdução a árvores Árvores com costura Percurso em ordem simétrica: D G B A H E I C F
184
Introdução a árvores Quinta lista de exercícios
185
Programação de algoritmos Rodrigo Reis Gomes Bacharel em Informática – UFRJ – 1999 Mestre em Modelagem Computacional – UERJ – 2003 Doutor em Modelagem Computacional – UERJ – 2012 rodrigoreisgomes@gmail.com
Apresentações semelhantes
© 2024 SlidePlayer.com.br Inc.
All rights reserved.