Programação de algoritmos Rodrigo Reis Gomes Bacharel em Informática – UFRJ – 1999 Mestre em Modelagem Computacional – UERJ – 2003 Doutor em Modelagem.

Slides:



Advertisements
Apresentações semelhantes
Estruturas de Dados Listas Prof. Rodrigo Rocha
Advertisements

LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello.
ESTRUTURA DE DADOS Professor: Marcelo Mendes Turma: MBI-1
Estruturas de Dados Marcio Gonçalves.
Marco Antonio Montebello Júnior
TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS ESTRUTURAS DE DADOS AVANÇADAS Aula /08/2011 Professor Leomir J. Borba-
Recursividade Prof. Rosana Palazon.
Algoritmos de manipulação de estruturas elementares de dados
Estrutura de Dados e Algoritmos e Programação e Computadores II
1 Complexidade de Algoritmos Complexidade de pior caso Complexidade de melhor caso de uso bem menos freqüente em algumas situações específicas Complexidade.
Árvores.
1 MergeSort Seja uma lista A de n elementos. O algoritmo consiste das seguintes fases Dividir A em 2 sub-listas de tamanho n/2 Conquistar: ordenar cada.

David Menotti Algoritmos e Estruturas de Dados I DECOM – UFOP
Pesquisa em Memória Primária
Pesquisa em Memória Primária – Árvores de Busca
Medida do Tempo de Execução de um Programa
Pesquisa em Memória Primária – Árvores de Busca
Medida do Tempo de Execução de um Programa
Pesquisa em Memória Primária
Árvores Introdução e Aplicações Árvores de Busca Binária Fundamentos
Ordenação Facilitar e aumentar a eficiência das operações de pesquisa sobre esses dados Pode ser crescente ou decrescente A seqüência de entrada, normalmente,
Ordenação Facilitar e aumentar a eficiência das operações de pesquisa sobre esses dados Pode ser crescente ou decrescente A seqüência de entrada, normalmente,
Análise Léxica Supondo o trecho de programa abaixo:
Listas com Ponteiros Listas encadeadas Listas circulares.
Lista Encadeada Circular Lista Duplamente Encadeada
Listas Encadeadas.
Fundamentos sobre Árvores
Prof. Hilton Cardoso Marins Junior
Algoritmos e Estruturas de Dados
Prof. Hilton Cardoso Marins Junior LISTA LINEAR
Pesquisa em Memória Primária
Linguagem de Programação II Parte IX
Denise Guliato Faculdade de Computação – UFU
Listas lineares Denise Guliato Faculdade de Computação – UFU
Árvores Binárias de Pesquisa
Algorítmos e estrutura de dados III
Lista Encadeada Circular Lista Duplamente Encadeada
Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação
Aula 03 – BCC202 Análise de Algoritmos (Parte 1) Túlio Toffolo www
Denise Guliato Faculdade de Computação – UFU
Listas, Filas e Pilhas Katia Guimarães.
Estruturas de Dados Aula 9: Listas (parte 1)
Á R V O R E S.
© Copyright 2007 Algoritmos e Estruturas de Dados - Todos os direitos reservados Átila Valgueiro Malta Moreira Juliana Medeiros de Lucena Rafael Alberto.
Estruturas de Dados PROFESSOR DIÓGENES FURLAN. Estruturas de Dados (ED) Programas operam sobre dados Dados são relacionados e possuem estrutura Como representar.
Estruturas de Dados Aula 11: TAD Pilha
Árvore Binária de Busca
Educação Profissional Técnica de Nível Médio Curso Técnico de Informática Disciplina: Estrutura de Dados Professor: Cheli dos S. Mendes da Costa Listas.
Educação Profissional Técnica de Nível Médio Curso Técnico de Informática
Educação Profissional Técnica de Nível Médio Curso Técnico de Informática
Árvores Binárias Profa. Patrícia A. Jaques Luiz Gonzaga Jr
Estruturas de Dados Aula 15: Árvores
Prof. Hilton Cardoso Marins Junior ÁRVORES BINÁRIAS.
Capítulo VI – Variáveis Indexadas 6.1 – A necessidade de variáveis indexadas 6.2 – Vetores e matrizes 6.3 – Aplicações com vetores numéricos 6.4 – Aplicações.
© 2011 Pearson Prentice Hall. Todos os direitos reservados.slide 1 © 2011 Pearson Prentice Hall. Todos os direitos reservados.slide 1 © 2011 Pearson Prentice.
Prof. Hilton Cardoso Marins Junior
Prof. Alessandro Gonçalves
Complexidade de Computação Katia Guimarães. Avaliando a Qualidade de um Algoritmo É preciso ter bem definido –O que é dado de entrada e –O que é esperado.
Introdução a Árvores e Árvores Binárias
© Copyright 2007 Algoritmos e Estruturas de Dados - Todos os direitos reservados Estruturas de Dados Dinâmicas IF672 - Algoritmos e Estruturas de Dados.
Estruturas de Dados Murilo Salgado Razoli.
Exercícios Faça um algoritmos para trocar uma lampada queimada.
Estrutura de Dados Aula 3 - Listas
Profa. Juliana Mafra ESTRUTURA DE DADOS 30 de Setembro de 2009 Faculdade de Informática e Tecnologia de Pernambuco.
Árvores e Árvores Binárias
11 Pilhas, Filas e Listas Duplamente Encadeadas Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)
BANCO DE DADOS II Árvore de Dados. FATEC - GUARATINGUETÁ Professor: Eduardo Barbosa Adiel Lemos Ana Renata Bruno Michael Jéssica Fernanda Layla Monique.
Alocação Dinâmica Dilvan Moreira. Objetivos  Entender o que são e como usar:  Gerenciamento de Memória  Alocação Dinâmica em C.
INE5408 Estruturas de Dados Árvores B - Estrutura e peculiaridades -Algoritmos de inserção, pesquisa e deleção.
Transcrição da apresentação:

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

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

Ementa  Complexidade de algoritmos  Alocação sequencial  Alocação encadeada  Algoritmos de ordenação  Introdução a árvores

Bibliografia Eslaides: Bibliografia básica: 1. SZWARCFITER, Jayme Luiz; MARKENZON, Lilian. Estrutura de dados e seus algoritmos. 2a Edição. Rio de Janeiro: LTC, TENENBAUM, Aaron M.; LANGSAM, Yedidyah; AUGENSTEIN, Moshe J. Estrutura de dados usando C. São Paulo: Makron, 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, Bibliografia complementar: 1. GUIMARÃES, Angelo de Moura; LAGES, Newton Alberto de Castilho. Algoritmos e Estruturas de Dados. Rio de Janeiro: LTC, EDELWEISS, Nina; GALANTE, Renata. Estruturas de Dados. Porto Alegre: Bookman, PEREIRA, Silvio do Lago. Estrutura de dados fundamentais : conceitos e aplicações. 12.ed. rev. e ampl. São Paulo: Érica, VELOSO, Paulo A. S. Estruturas de dados. Rio de Janeiro: Elsevier: Campus, c TOSCANI, Laira V.; VELOSO, Paulo A. S. Complexidade de algoritmos: análise, projeto e métodos. 3.ed. Porto Alegre: Bookman, 2012.

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

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

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

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

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; }

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];

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]; }

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

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

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 )

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

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; }

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;

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); }

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

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

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); }

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); }

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); }

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); }

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); }

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);

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);

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);

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);

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);

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);

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);

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);

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);

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); }

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); }

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); }

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);

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);

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); }

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); }

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); }

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); }

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);

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

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?

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

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

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

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

Complexidade de algoritmos Primeira lista de exercícios

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

Alocação sequencial Motivação: listas de números inteiros Como implementar?  int lista[?]; 10, 50, ???

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])); lista

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 NULL

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);

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; }

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; }

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; }

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 }

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 }

Alocação sequencial Segunda lista de exercícios

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

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

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

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 = v t = ? m = 5

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

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

Alocação sequencial Pilhas de números inteiros Quantidade de elementos na pilha: int elementosNaPilha(struct TPilha p) { return p.t + 1; }

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; }

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 }

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 }

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); }

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

Alocação sequencial Continuação da segunda lista de exercícios

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

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

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

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

Alocação encadeada Listas encadeadas  Lista de caracteres  Representação de cada nó da lista struct TNoDeCaractere { char caractere; struct TNoDeCaractere * proximo; };

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;... }

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.

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 { 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 }

Alocação encadeada Listas encadeadas (criação de novo nó)  Em uma lista vazia Estrutura inicial:

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”.

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”.

Alocação encadeada Listas encadeadas (criação de novo nó)  Em uma lista vazia Estrutura atual:

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;

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;

Alocação encadeada Listas encadeadas (criação de novo nó)  Em uma lista vazia Estrutura atual:

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;

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;

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.

Alocação encadeada Listas encadeadas (criação de novo nó)  No final de uma lista Estrutura atual:

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;

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;

Alocação encadeada Listas encadeadas (criação de novo nó)  No final de uma lista Estrutura atual:

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

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.

Alocação encadeada Listas encadeadas (criação de novo nó)  No final de uma lista Estrutura atual:

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));

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));

Alocação encadeada Listas encadeadas (criação de novo nó)  No final de uma lista Estrutura atual:

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;

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;

Alocação encadeada Listas encadeadas (criação de novo nó)  No final de uma lista Estrutura atual:

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;

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;

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.

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 }

Alocação encadeada Listas encadeadas (exclusão do primeiro nó)  Estrutura atual:

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;

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;

Alocação encadeada Listas encadeadas (exclusão do primeiro nó)  Estrutura atual:

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”.

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”.

Alocação encadeada Listas encadeadas (exclusão do primeiro nó)  Estrutura atual:

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;

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;

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.

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

Alocação encadeada Listas encadeadas (exclusão de nó genérico)  Estrutura atual: pAnt p

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

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.

Alocação encadeada Filas (FIFO – First In, First Out)  O primeiro a entrar é o primeiro a sair  Como uma fila de cinema  Exemplo:

Alocação encadeada Filas (FIFO – First In, First Out)  O primeiro a entrar é o primeiro a sair  Como uma fila de cinema  Exemplo:

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!

Alocação encadeada Pilhas (LIFO – Last In, First Out)  O último a entrar é o primeiro a sair  Como uma pilha de rascunhos  Exemplo:

Alocação encadeada Pilhas (LIFO – Last In, First Out)  O último a entrar é o primeiro a sair  Como uma pilha de rascunhos  Exemplo:

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!

Alocação encadeada Terceira lista de exercícios

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”

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”

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

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

Alocação encadeada Terceira lista de exercícios (continuação)

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

Algoritmos de ordenação Método da bolha (bubble sort)

Algoritmos de ordenação Método da bolha (bubble sort) No final da primeira iteração, o último elemento é certamente o maior.

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.

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...

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.

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.

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.

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)

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)

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)

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) mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)

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) mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)

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) mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)

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, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)

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) mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)

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) mergeSort(v, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)

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, tam/2) mergeSort(v+tam/2, tam-tam/2) ordenar(v, tam)

Algoritmos de ordenação Quarta lista de exercícios

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

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

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

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

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.

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

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

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.

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

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

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.

Introdução a árvores Árvores binárias d) Zigue-zague: Cada nó interior (não folha) possui exatamente um filho

Introdução a árvores Armazenamendo de árvores binárias struct TNoDeArvoreBinaria { char info; struct TNoDeArvoreBinaria * esq; struct TNoDeArvoreBinaria * dir; } * raiz;

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

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

Introdução a árvores Exclusão em árvores binárias  Nó folha: Excluir e fazer o pai passar a apontar para nada

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

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

Introdução a árvores Árvores m-árias  Generalização da árvore binária  Cada nó possui m subárvores Exemplo: Árvores ternárias

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.

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.

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’

Introdução a árvores Conversão de árvore em árvore binária

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

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ó

Introdução a árvores Árvores com costura

Introdução a árvores Árvores com costura Percurso em ordem simétrica: D G B A H E I C F

Introdução a árvores Árvores com costura Percurso em ordem simétrica: D G B A H E I C F

Introdução a árvores Quinta lista de exercícios

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