Enunciados das aulas práticas de. Algoritmos e Modelação Matemática

Documentos relacionados
Prova 2 PMR2300 1o. semestre 2015 Prof. Thiago Martins

Departamento de Ciência de Computadores Estruturas de Dados (CC114)

Prova 2 PMR3201 1o. semestre 2015 Prof. Thiago Martins

UNIP - Ciência da Computação e Sistemas de Informação. Estrutura de Dados. AULA 5 Pilhas

Árvores. Fabio Gagliardi Cozman. PMR2300 Escola Politécnica da Universidade de São Paulo

Árvores. Thiago Martins, Fabio Gagliardi Cozman. PMR2300 / PMR3201 Escola Politécnica da Universidade de São Paulo

Árvores. Thiago Martins, Fabio Gagliardi Cozman. PMR2300 / PMR3201 Escola Politécnica da Universidade de São Paulo

Departamento de Ciência de Computadores Estruturas de Dados (CC114)

Prova 2 PMR3201 1o. semestre 2016 Prof. Thiago Martins

Grupo 2 - Implementação de uma Classe Simples

T(0) = 0 T(n) = 2*T((n-1)/2) + 1

Prova de Recuperação PMR3201/PMR2300 1o. semestre 2015 Prof. Thiago Martins

Departamento de Ciência de Computadores Estruturas de Dados (CC114)

UNIVERSIDADE DA BEIRA INTERIOR

Departamento de Ciência de Computadores Estruturas de Dados (CC114) FCUP 2010/11. 2 o Teste: 20/Junho/2011

Árvores Estrutura de Dados. Universidade Federal de Juiz de Fora Departamento de Ciência da Computação

Lista 1 - PMR2300. Fabio G. Cozman 3 de abril de 2013

Estruturas de dados e algoritmos fundamentais

ESTRUTURAS DE DADOS E ALGORITMOS LISTA LIGADA

Árvores Binárias de Busca

Lista 1. 8 de abril de Algorithms: Capítulo 0, exercícios 1 e 2. Tardos: Todos exercícios do cap 2 do livro texto, exceto 7 e 8 letra b.

ESTRUTURAS DE DADOS E ALGORITMOS LISTA LIGADA (ABORDAGEM RECURSIVA)

Técnicas de projeto de algoritmos: Indução

Prova Substitutiva PMR3201/PMR2300 1o. semestre 2015 Prof. Thiago Martins

INSTITUTO SUPERIOR TÉCNICO Algoritmos e Estruturas de Dados

Exame de Estruturas de Dados 2010.Junho.26

Árvores Binárias. SCC Algoritmos e Estruturas de Dados I. Prof. Fernando V. Paulovich

FCUP 2010/11. Departamento de Ciência de Computadores Estruturas de Dados (CC114) 1 o Teste: 27/Abril/2011

SIN Exemplo de Prova do Conteúdo Semestral

QUESTÕES DE PROVAS ANTIGAS

Resposta da pergunta 2: Θ(n 3 ). Resposta da pergunta 8: 1. 7 O(n). Sim. 22. n log n O(1). Não. 3. n + 7 O(n). Sim. 4. n + 7 O(1). Não.

Edital de Seleção 053/2016 PROPESP/UFAM. Prova de Conhecimento. Caderno de Questões

MAC121 ALGORITMOS E ESTRUTURAS DE DADOS I 2O. SEMESTRE DE 2017

Usando o Eclipse - Fundamentos. Professor Vicente Paulo de Camargo

Prova 1 PMR2300 / PMR3201 1o. semestre 2015 Prof. Thiago Martins

Listas Estáticas. SCC Algoritmos e Estruturas de Dados I. Prof. Fernando V. Paulovich. *Baseado no material do Prof.

Árvores. Estruturas de Dados. Prof. Vilson Heck Junior

Prof. Jesus José de Oliveira Neto

INSTITUTO SUPERIOR TÉCNICO Algoritmos e Estruturas de Dados

Palavras Reservadas da Linguagem Java

Estruturas de Dados II

Programação Orientada a Objectos - P. Prata, P. Fazendeiro

RESULUÇÃO DOS EXERCÍCIOS E INSTRUÇÕES DE DECISÃO (if{} e else{}) Profº André Aparecido da Silva Disponível em:

Lista 2 - PMR2300/3200

Problema do Caminho Hamiltoniano

INSTITUTO SUPERIOR TÉCNICO Introdução aos Algoritmos e Estruturas de Dados

Algoritmos e Estrutura de Dados II. Árvore. Prof a Karina Oliveira.

Árvores Binárias de Busca

Estruturas de Dados Encadeadas

Filas de prioridade. Marcelo K. Albertini. 3 de Dezembro de 2013

Apêndice A. Alguns construtores e métodos importantes e úteis da classe Vector são:

Introdução aos Algoritmos e Estruturas de Dados. 2 o Teste - A

Fabrício J. Barth. BandTec - Faculdade de Tecnologia Bandeirantes

Exame de Admissão. Instituto Nacional de Pesquisas Espaciais 18 de setembro de 2018 A: GABARITO

Árvores e Mapas. Luís Lopes. Estruturas de Dados DCC-FCUP

Filas de prioridade. Marcelo K. Albertini. 27 de Novembro de 2014

Filas de Prioridade. Uma fila de prioridade pode ser vista como uma generalização das filas com as seguintes duas operações:

AED2 - Aula 22 Busca em largura, cálculo de distâncias

Fila e Deque. SCC Algoritmos e Estruturas de Dados I. Prof. Fernando V. Paulovich. *Baseado no material do Prof.

Grupo 2 - Implementação de uma classe simples

UNIVERSIDADE DA BEIRA INTERIOR

RESPOSTA: import java.util.arraylist; import java.util.list; class CarrinhoDeCompras2 { List<Produto> produtos;

Edital de Seleção 024/2017 PROPESP/UFAM. Prova de Conhecimento. Caderno de Questões

Sobrecarga. Algoritmos e Programação II. Aula 3 Sobrecarga

Lista Ordenada. Estrutura de Dados. Universidade Federal de Juiz de Fora Departamento de Ciência da Computação 1 / 35

Estruturas de Dados Filas

Universidade Federal do Ma Curso de Ciência da Computação

Busca Binária. Aula 05. Busca em um vetor ordenado. Análise do Busca Binária. Equações com Recorrência

Estruturas de dados e algoritmos fundamentais

Ordenação: QuickSort. Prof. Túlio Toffolo BCC202 Aula 15 Algoritmos e Estruturas de Dados I

INF 1620 P2-01/11/03 Questão 1 Nome:

Classes, Herança e Interfaces

Aula 7 e 8 Filas e suas Aplicações. Prof. Leticia Winkler

Projeto e Análise de Algoritmos

1 Da aula teórica ao Java

6. Pesquisa e Ordenação

Prova Substitutiva PMR3201 1o. semestre 2018 Prof. Thiago Martins

MAC121 ALGORITMOS E ESTRUTURAS DE DADOS I 2O. SEMESTRE DE 2017

Recursividade. Métodos iterativos. Prof. Cesar Augusto Tacla. Métodos iterativos utilizam estruturas de repetição

Lista 05 Herança. public class PessoaFisica extends Pessoa { private String RG; public PessoaFisica(){ super(); } public String getrg(){ return RG; }

Aulas de. Algoritmos e Modelação Matemática

INF 1010 Estruturas de Dados Avançadas

Filas. Prof. Túlio Toffolo BCC202 Aula 12 Algoritmos e Estruturas de Dados I

1. Cotação de cada pergunta: / / (Total: 100 pontos) 2. Responda às questões de forma clara e concisa nas folhas de exame.

ESTRUTURA DE DADOS E ALGORITMOS HEAPS E LISTAS DE PRIORIDADES

Árvores de Pesquisa. A árvore de pesquisa é uma estrutura de dados muito eficiente para armazenar informação.

ESTRUTURAS DE DADOS E ALGORITMOS HEAP BINÁRIA

UNIVERSIDADE DA BEIRA INTERIOR

Análise e Complexidade de Algoritmos

CAL ( ) MIEIC/FEUP Estruturas de Dados ( )

Heaps. Estrutura de Dados. Universidade Federal de Juiz de Fora Departamento de Ciência da Computação 1 / 35

Teoria dos Grafos Aula 6

double x; x = enigmab1(100);

Grafos: Busca. SCE-183 Algoritmos e Estruturas de Dados 2. Thiago A. S. Pardo Maria Cristina

Estrutura de Dados: Aula 3 - Linguagem C

UNIVERSIDADE DA BEIRA INTERIOR

Programação Orientada a Objectos - P. Prata, P. Fazendeiro

Transcrição:

Enunciados das aulas práticas de Algoritmos e Modelação Matemática Paulo Mateus André Souto 2013

ii À guardiã

Precaução dirigida aos alunos Os temas apresentados neste trabalho são uma versão muito preliminar da sebenta da cadeira de Algoritmos e Modelação Matemática dos cursos de Engenharia Biomédica e de Matemática Aplicada à Computação do Instituto Superior Técnico da Universidade de Lisboa. Notem que pode haver gralhas, exemplos incompletos, definições e teoremas que podem estar apresentados de forma não uniforme. Na verdade podem existir tópicos que necessitarão de ser reescritos ou escritos de raiz. Parte dos exercícios são retirados das referências bibliográficas dadas. Futuramente, serão substituídos por outros que possam servir os nossos propósitos enquanto docentes da cadeira e de acordo com os objetivos estabelecidos para os conhecimentos a adquirir pelos alunos. No que diz respeito a esta notas o leitor deve estar preparado para se deparar com problemas de compreensão das matérias abordadas, dado que serão para já muito incompletas, e portanto sugerimos a leitura de livros considerados importantes nas áreas que serão abordadas de modo a complementarem a informação apresentada. Sugerimos por exemplo a leitura de [?], [?] e outras referências que faremos ao longo deste trabalho. iii

Prefácio Este trabalho tenciona compilar num livro os conteúdos programáticos de um curso introdutório à Algoritmia e à Modelação Matemática. Os temas abordados neste trabalho são naturalmente parte integrante dos conteúdos programáticos planeados para a cadeira de Algoritmos e Modelação Matemática a lecionar nos cursos de Engenharia Biomédica e de Matemática Aplicada à Computação do Instituto Superior Técnico da Universidade de Lisboa. A primeira compilação data do ano de 2013. A ideia deste trabalho é providenciar ao alunos (e não só) uma referência de estudo, ainda que incompleta, sobre algoritmia com uma forte componente matemática de análise e correção sendo por isso dado um especial enfase a estas problemática sob o ponto de vista de matemático e do ponto de vista das ciências da computação. A juntar a este objetivo pretende-se que este compêndio possa futuramente ser também uma ferramenta útil para outros cursos que abordem temáticas semelhantes. Pelo apoio financeiro, o autor André Souto está profundamente grato à Fundação para a Ciência e Tecnologia pela bolsa SFRH/BPD/76231/2011. Estamos também gratos a todos os membros do SQIG pelo excelente ambiente de trabalho pelo encorajamento dado. Ficamos também gratos aos alunos por qualquer comentário que ajudem a melhorar este trabalho. 2012. Departamento de Matemática Instituto Superior Técnico, Universidade de Lisboa Security and Quantum Information Group v

Instituto de Telecomunicações Conteúdo Precaução dirigida aos alunos Prefácio iii v Conteúdo 1 1 Introdução ao Eclipse 3 1.1 Exercícios propostos para a aula................................. 3 1.1.1 Criação de um projeto no Eclipse............................. 4 1.1.2 Compilação, Debugging e correção dos programas.................. 4 2 Implementação de dados abstratos 11 2.1 Exercícios propostos para a aula................................. 11 2.2 Exercícios propostos adicionais.................................. 13 3 Notação assimptótica 25 3.1 Exercícios propostos para a aula................................. 25 4 Pesquisa binária e árvores de pesquisa 31 4.1 Exercícios propostos para a aula................................. 31 5 Grafos com matrizes de adjacência 35 5.1 Exercício propostos para a aula.................................. 35 5.2 Exercícios propostos........................................ 36 6 Pesquisa em profundidade em grafos 39 6.1 Exercícios propostos para a aula................................. 39 1

Prática 1 Introdução ao Eclipse Exercícios propostos para a aula SECÇÃO 1.1 A primeira aula de laboratório tem como objetivo a introdução à escrita, compilação e debugging de programas escritos em Java, utilizando o ambiente de desenvolvimento integrado Eclipse. Pretende-se nesta aula implementar um programa que realiza um conjunto de operações sobre números naturais. Ao longo da aula serão realizadas as seguintes tarefas: 1. criação e configuração de um novo projeto no Eclipse; 2. compilação, debugging e correção do programa; 3. implementação recursiva de algumas operações. 3

1.1.1 Criação de um projeto no Eclipse 1. Comece por entrar na sua área de trabalho, com o login e password do Fenix. Inicie o programa Eclipse Juno. 2. Crie um novo projecto File > New Java Project. Coloque o título Aula1. 3. Crie uma nova classe File > New Class. Coloque no nome Utils e verifique as opções. 4. Está pronto para desenvolver funções de pacotes de utilitários. 1.1.2 Compilação, Debugging e correção dos programas 1. Crie a função fatorial. Teste a função para alguns valores fazendo output destes valores; 2. Depure o programa: Crie breakpoints e entre na vista de Debug. 3. Implemente recursivamente a função fatorial e depure-a. 4. Escreva um algoritmo de ordenação à sua escolha. Depure o programa criado. 5. Escreva uma função que calcula o traço de uma matriz. 6. Escreva um função que testa se um dado elemento ocorre num vetor. Melhore a função anterior supondo que o vetor recebido está ordenado. 4

Algumas propostas de resolução Apresenta-se algum do código da resolução de alguns exercícios da aula. O código para a implementação do cálculo da função fatorial quando é dado um número n: 1 public class Utils { 2 3 public static void main ( String [] args ) { 4 int n =4; 5 boolean x; 6 x= teste (n); 7 if(x == true ){ 8 System. out. println ("O valor de " + n+"! e :" + factorial (n)); 9 } else { 10 System. out. println ("O valor de " + n+" esta incorrecto."); 11 } 12 } 13 14 private static boolean teste ( int n) { 15 if(n >0) { 16 return true ;} 17 else { 18 return false ; 19 } 20 } 21 5

22 private static int factorial ( int n) { 23 int i=1, r =1; 24 while (i< n){ 25 i ++; 26 r*=i; 27 } 28 return r; 29 } 30 } A implementação de forma recursiva pode ser feita através do seguinte código: 1 public class Utils2 { 2 3 public static void main ( String [] args ) { 4 int n =6; 5 boolean x; 6 x= teste (n); 7 if(x == true ){ 8 System. out. println ("O valor de " + n+"! e :" + fatorial (n)); 9 } else { 10 System. out. println ("O valor de " + n+" esta incorreto."); 11 } 12 } 13 14 private static boolean teste ( int n) { 15 if(n >0) { 16 return true ;} 17 else { 18 return false ; 19 } 20 } 6

21 22 private static int factorial ( int n) { 23 if(n ==1) { 24 return 1; 25 } 26 else { 27 return n* factorial (n -1) ; 28 } 29 } 30 } Uma possível implementação da ordenação de um vetor pode ser idealizado através de: 1 public class Utils3 { 2 3 public static void main ( String [] args ) { 4 int vec []; 5 vec = new int [4]; 6 vec [0]=1; 7 vec [1]=5; 8 vec [2]=3; 9 vec [3]=2; 10 int i; 11 i =0; 12 while (i< vec. length ){ 13 int j=i,min = vec [i], pos =i; 14 int aux ; 15 while (j< vec. length ){ 16 if(vec [j]< min ){ 17 pos =j; 18 } 19 aux = vec [i]; 20 vec [i]= vec [ pos ]; 21 vec [ pos ]= aux ; 7

22 j ++; 23 } 24 i ++; 25 } 26 System. out. println ( vec [0] + ";" + vec [1] + ";" + vec [2] + ";" + vec [3]) ; 27 } 28 } Uma possível implementação do cálculo do traço de uma matriz é: 1 public class Utils5 { 2 3 public static void main ( String [] args ) { 4 double mat [][]; 5 mat = new double [2][2]; 6 mat [0][0]=1.5; 7 mat [0][1]=5.5; 8 mat [1][0]=3.3; 9 mat [1][1]=2.2; 10 int i =0; 11 double soma =0; 12 while (i <= mat. length -1) { 13 soma += mat [i][i]; 14 i ++; 15 } 16 System. out. println ( soma ); 17 } 18 // } A implementação do teste de ocorrência de um número num vetor: 8

1 public class Utils6 { 2 3 public static void main ( String [] args ) { 4 int vec []; 5 vec = new int [4]; 6 vec [0]=1; 7 vec [1]=5; 8 vec [2]=3; 9 vec [3]=2; 10 int n= 6; 11 boolean r; 12 r= ocorrencia (vec,n); 13 if(r == true ){ 14 System. out. println ("O valor ocorre "); 15 } else { 16 System. out. println ("O valor nao ocorre "); 17 } 18 } 19 20 21 private static boolean ocorrencia ( int [] vec, int n) { 22 int i =0; 23 while (i <= vec. length -1) { 24 if(vec [i ]== n){ 25 return true ;} 26 i ++; 27 } 28 return false ;} 29 } 9

Prática 2 Implementação de dados abstratos Exercícios propostos para a aula SECÇÃO 2.1 Considere o tipo de dados lista ordenada implementado em Java da seguinte forma: 1 class Node { 2 int val ; 3 Node next ; 4 } 5 6 public class Lista { 7 int comp ; 8 Node prim ; 9... 10 } 11

Implemente a classe lista com a seguinte interface 1. ins: recebe um inteiro acrescenta à lista o inteiro de forma a que esta se mantenha ordenada (por ordem crescente). 2. vazq: testa se a lista é vazia. 3. pert: recebe um inteiro e verifica se o inteiro pertence à lista. 4. ret: recebe um inteiro e apaga uma ocorrência do inteiro na lista. 5. apaga: recebe uma lista e apaga todos os elementos da lista. 12

SECÇÃO 2.2 Exercícios propostos adicionais 1. Implemente a classe da página anterior com um nó bidirecional. 2. Suponha que cerca de 70% inserções correspondem a inserir um elemento maior que todos os elementos que se encontram na lista. Faça alterações à implementação do tipo de dados lista para que a implementação da função ins tenha o custo médio mais baixo possível. Indique qual o número médio de comparações necessárias para inserir um elemento supondo que nos restantes 30% dos casos o elemento a colocar poderá ser colocado em qualquer posição (exceto a última) com igual probabilidade. 3. Usando a classe de nó do Exercício 1, implemente uma lista circular (não ordenada) onde o primeiro e último elemento estão ligados. Considere as seguintes funções: a) O construtor retorna a lista vazia. b) ins: recebe um inteiro e acrescenta o inteiro no fim da lista. c) vazq: testa se a lista é vazia. d) pert: recebe um inteiro e verifica se o inteiro pertence à lista. e) ret: recebe um inteiro e apaga uma ocorrência do inteiro da lista. f) apaga: recebe uma lista e apaga todos os elementos da lista. 13

Algumas propostas de resolução O código para a implementação de uma lista com o respetivo interface: 1 public interface Lista { 2 void ins ( int i); 3 boolean vazq (); 4 boolean pert ( int i); 5 void ret ( int i); 6 void apaga (); 7 } 1 public class Node { 2 int val ; 3 Node next ; 4 5 Node ( int v){ 6 val =v; 7 next = null ; 8 } 9 } 1 public class ImpLista implements Lista { 2 15

3 int comp ; 4 private Node prim ; 5 6 public void ins ( int i) { 7 Node n= new Node (i); 8 // Node aux = prim ; 9 if ( comp ==0) { 10 prim =n; 11 comp =1; 12 } 13 if( prim. val >= i){ 14 n. next = prim ; 15 prim = n; 16 } 17 Node aux = prim ; 18 int j =1; 19 while ( aux. next.val < i && j< comp -1) { 20 aux = aux. next ; 21 j ++; 22 } 23 if(j== comp -1) { 24 j=j -1; 25 aux. next =n; 26 n. next = null ; 27 } else { 28 Node aux2 = aux. next ; 29 aux. next =n; 30 n. next = aux2 ; 31 } 32 comp = comp +1; 33 } 34 35 public boolean vazq () { 36 return comp ==0; 37 } 38 16

39 public boolean pert ( int i) { 40 int j =1; 41 Node aux = prim ; 42 while (j< comp ){ 43 if(aux. val == i) return true ; 44 j ++; 45 } 46 return false ; 47 } 48 49 public void ret ( int i) { 50 if( pert (i)== true ){ 51 if( comp ==1 && prim. val ==i){ 52 comp =0; 53 prim = null ; 54 } else { if( prim. val ==i){ 55 prim = prim. next ; 56 comp =comp -1; 57 } else { 58 Node aux1 = prim ; 59 Node aux2 = aux1. next ; 60 while ( aux2. val!=i){ 61 aux2 = aux2. next ; 62 aux1 = aux1. next ; 63 64 aux1. next = aux2. next ; 65 comp =comp -1; 66 } 67 } 68 } 69 } 70 71 public void apaga () { 72 comp =0; 73 prim. val = -1; 74 prim. next = null ; } 17

75 } 76 } O código para a implementação de uma lista bidirecional com o respetivo interface: 1 public interface Listabi { 2 3 void ins ( int i); 4 boolean vazq (); 5 boolean pert ( int i); 6 void ret ( int i); 7 void apaga (); 8 } 1 public class Nobi { 2 int val ; 3 Nobi next ; 4 Nobi previous ; 5 6 Nobi ( int v){ 7 val =v; 8 next = null ; 9 previous = null ; 10 } 11 } 1 public class Implistabi implements Listabi { 2 3 int comp ; 4 private Nobi prim ; 18

5 6 public void ins ( int i) { 7 Nobi n= new Nobi (i); 8 // Node aux = prim ; 9 if ( comp ==0) { 10 prim =n; 11 comp =1;} 12 if( prim. val >= i){ 13 n. next = prim ; 14 n. next. previous =n; 15 prim =n; 16 } 17 Nobi aux = prim ; 18 int j =1; 19 while ( aux. next.val < i && j< comp -1) { 20 aux = aux. next ; 21 j ++; 22 } 23 if(j== comp -1) { 24 n. previous = aux ; 25 n. next = null ; 26 } else { 27 n. next = aux. next ; 28 n. previous = aux. previous ; 29 } 30 comp = comp +1; 31 } 32 33 public boolean vazq () { 34 return comp ==0; 35 } 36 37 public boolean pert ( int i) { 38 int j =1; 39 Nobi aux = prim ; 40 while (j< comp ){ 19

41 if(aux. val == i) return true ; 42 j ++; 43 } 44 return false ; 45 } 46 47 public void ret ( int i) { 48 if( pert (i)== true ){ 49 if( prim. val ==i){ 50 prim = prim. next ; 51 prim. previous = null ; 52 comp =comp -1; 53 } else { 54 Nobi aux = prim ; 55 while ( aux. val!=i){ 56 aux = aux. next ; 57 } 58 aux. next. previous = aux. previous ; 59 comp =comp -1; 60 } 61 } 62 } 63 64 public void apaga () { 65 comp =0; 66 prim. val = -1; 67 prim. next = null ; 68 prim. previous = null ; 69 } 70 71 } O código para a implementação de uma lista circular com o respetivo interface: 20

1 public interface Listacircular { 2 void nova (); 3 void ins ( int i); 4 boolean vazq (); 5 boolean pert ( int i); 6 void ret ( int i); 7 void apaga (); 8 } 1 public class Implistacircular implements Listacircular { 2 3 int comp ; 4 protected Node prim ; 5 6 public void nova () { 7 prim = null ; 8 comp =0; 9 } 10 11 public void ins ( int i) { 12 Node n = new Node (i); 13 if( comp ==0) { 14 prim =n; 15 n. next =n; 16 comp = comp +1; 17 } else { 18 int j =1; 19 Node aux = prim ; 20 while (j< comp ){ 21 aux = aux. next ; 22 j ++; 23 } 24 n. next = prim ; 25 aux. next =n; 21

26 } 27 } 28 29 public boolean vazq () { 30 return comp ==0; 31 } 32 33 public boolean pert ( int i) { 34 int j =1; 35 Node aux = prim ; 36 while (j< comp ){ 37 if(aux. val == i) return true ; 38 j ++; 39 } 40 return false ; 41 } 42 43 public void ret ( int i) { 44 if( pert (i)== true ){ 45 if( comp ==1 && prim. val ==i){ 46 comp =0; 47 prim = null ; 48 } else { if( prim. val ==i){ 49 prim = prim. next ; 50 comp =comp -1; 51 } else { 52 Node aux1 = prim ; 53 Node aux2 = aux1. next ; 54 while ( aux2. val!=i){ 55 aux2 = aux2. next ; 56 aux1 = aux1. next ; 57 } 58 aux1. next = aux2. next ; 59 comp =comp -1; 60 } 61 } 22

62 } 63 } 64 65 public void apaga () { 66 comp =0; 67 prim. val = -1; 68 prim. next = null ; 69 } 70 } 23

Prática 3 Notação assimptótica No exercícios que se seguem o aluno deve ter em atenção que podem ser usadas notações diferentes para a notação assimptótica. Em algumas literaturas é usado o símbolo de pertença enquanto que noutras é usado o sinal de igual com a interpretação óbvia. Exercícios propostos para a aula SECÇÃO 3.1 1. Assuma que os termos que se seguem expressão o tempo T(n) gasto por um algoritmo na resolução de um problema para instâncias de tamanho n. Indique o termo dominante e a menor complexidade Oh-grande de cada exemplo. a) 5 + 0.001n 3 + 0.025n b) 500n + 100n 1,5 + 50n log 10 n c) 2 n + 2.5n 1.75 d) n 2 + log 2 n + n(log 2 n) 25

e) 2n log 3 n + n log 2 n f) 3 log 8 n + log 2 log 2 log 2 n g) 100n + 0.01n 2 h) 0.01n + 100n 2 i) 2n + n 0.5 + 0.5n 1.25 j) 0.01n log 2 n + n(log 2 n) 2 k) 100n log 3 n + n 3 + 100n l) 0.003 log 4 n + log 2 log 2 n 2. Diga quais das seguintes afirmações são verdadeiras. a) 3n 2 + 10n log n = O(n log n) b) 3n 2 + 10n log n = Ω(n 2 ) c) 3n 2 + 10n log n = Θ(n 2 ) d) n log n + n/2 = O(n) e) 10 n + log n = O(n) f) n + log n = O(log n) g) n + log n = Θ(log n) h) n + log n = Θ(n) i) 2 n + log n = Θ( n) j) n + log n = Ω(1) k) n + log n = Ω(log n) l) n + log n = Ω(n) 3. Diga quais das seguintes afirmações são verdadeiras. Corrija as falsas. a) O( f + g) = O( f ) + O(g); b) O( f g) = O( f ) O(g); c) g = O( f ) e h = O( f ) então g = O(h); d) n 4 = O(n 6 ); 26

e) 2 n+1 = O(2 n ); f) 2 2n = O(2 n ). 4. Prove rigorosamente que: a) 1 2 n2 3n = Θ(n 2 ); b) 6n 3 = Θ(n 2 ). 5. Ordene por ordem crescente na ordenação da notação Oh-grande as seguintes funções: log n; 2 n 3 ; n 5/2 ; 2 3 log n ; n; 4 n; log 3 n; n 10 ; 2 log n ; 2 3n ; log n 27

Algumas propostas de resolução 1. a) termo 0.001n 3 ; ordem O(n 3 ); b) termo 100n 1.5 ; ordem O(n 1.5 ); c) termo 2 n ; ordem O(2 n ); d) termo n 2 ; ordem O(n 2 ); e) termo são ambos; ordem O(n log n); f) termo 3 log 8 n; ordem O(log n); g) termo 0.01n 2 ; ordem O(n 2 ); h) termo 100n 2 ; ordem O(n 2 ); i) termo 0.5n 1.25 ; ordem O(n 1.25 ); j) termo n(log 2 n) 2 ; ordem O(n(log 2 n) 2 ); k) termo n 3 ; ordem O(n 3 ); l) termo 0.003 log 4 n; ordem O(log n); 2. a) falso; b) verdadeiro; c) verdadeiro; d) falso; e) verdadeiro; f) falso; g) falso; h) falso; 29

i) verdadeiro; j) verdadeiro; k) verdadeiro; l) falso; 3. Diga quais das seguintes afirmações são verdadeiras. Corrija as falsas. a) O( f + g) = O( f ) + O(g); Falso - O( f + g) = O(max{ f, g}) b) O( f g) = O( f ) O(g); Verdadeiro c) g = O( f ) e h = O( f ) então g = O(h); Falso - g = O( f ) e f = O(h) então g = O(h) d) n 4 = O(n 6 ); Verdadeiro e) 2 n+1 = O(2 n ); Verdadeiro f) 2 2n = O(2 n ). Falso 4. Prove rigorosamente que: a) 1 2 n2 3n = Θ(n 2 ); Para provar que 1 2 n2 3n O(n 2 ) basta notar que qualquer que seja o n natural 1 2 n2 3n n 2 pelo que basta tomar na definição de classe Oh n 0 = 1 e c = 1; Para provar que 1 2 n2 3n θ(n 2 ) note-se que: 1 2 n2 3n 1 3 n2 n 18 Basta então tomar na definição de Ω, c = 1/3 e n 0 = 18. b) 6n 3 = Θ(n 2 ). Claramente 6n 3 Ω(n 2 ) pois qualquer que seja o n 6n 3 n 2. Tem de se mostrar então que 6n 3 / Ø(n 2 ). Se 6n 3 Ø(n 2 ) então qualquer que fosse o c e existia n 0 tal que para todo o n n 0 6n 3 cn 2 ou seja n c/6 o que é impossível. 5. Ordene por ordem crescente na ordenação da notação Oh-grande as seguintes funções: log n log n log 3 n 4 n n 2 log n n 5/2 2 3 log n n 10 2 3n 2 n3 30

Prática 4 Pesquisa binária e árvores de pesquisa Exercícios propostos para a aula SECÇÃO 4.1 Implemente a pesquisa binária em vectores ordenados. Implemente a classe árvore ternária com os seguinte métodos: ArvTer() que constrói uma árvore vazia; ArvTer(int key, ArvTer l, ArvTer c, ArvTer d) que constrói uma árvore ternária com os descendentes óbvios; public boolean isheap() que retorna true se a árvore é um acervo, e falso caso contrário. public boolean pesquisa(int key) que assume que a árvore é um acervo e retorna true se a chave ocorre na árvore e false caso contrário. 31

Exercícios propostos 1. Implemente uma árvore com um número arbitrário de descendentes. 32

Algumas propostas de resolução 1 public class Trinode { 2 ArvTer ltree, ctree, rtree ; 3 int key ; 4 Trinode ( int i, ArvTer l, ArvTer c, ArvTer r){ 5 key =i; 6 ltree =l; 7 ctree =c; 8 rtree =r; 9 } 10 } 1 public class ArvTer { 2 Trinode root ; 3 4 public ArvTer () { 5 // TODO Auto - generated method stub 6 root = null ; 7 } 8 9 public ArvTer ( int key, ArvTer l, ArvTer c, ArvTer r) { 10 // TODO Auto - generated method stub 11 root = new Trinode (key, l, c, r); 12 } 13 33

14 public boolean isheap () { 15 if( root == null ) return true ; 16 if( root. ltree!= null && root. ltree. root!= null &&( root.key <= root. ltree. root. key! root. ltree. isheap ())) return false ; 17 if( root. ctree!= null && root. ctree. root!= null &&( root.key <= root. ctree. root. key! root. ctree. isheap ())) return false ; 18 if( root. rtree!= null && root. rtree. root!= null &&( root.key <= root. rtree. root. key! root. rtree. isheap ())) return false ; 19 return true ; 20 } 21 22 public boolean pesquisa ( int k) { 23 if( root == null ) return false ; 24 if( root.key >k) return false ; 25 if( root. key ==k) return true ; 26 return ( root. ltree!= null && root. ltree. pesquisa (k)) 27 ( root. ctree!= null && root. ctree. pesquisa (k) ) 28 ( root. rtree!= null && root. rtree. pesquisa (k) ); 29 } 30 } 34

Prática 5 Grafos com matrizes de adjacência Exercício propostos para a aula SECÇÃO 5.1 1. Implemente o tipo de dados grafo com matrizes de adjacência em Java com os seguintes métodos: classe grafo com o construtor que recebe a dimensão do grafo; adi aresta (recebe dois inteiro e adiciona a aresta entre os nós indexados pelos inteiros); rem aresta (recebe dois inteiro e retira a aresta entre os nós indexados pelos inteiros); adjacenteq (testa de se um nó é adjacente a outro); acessível (testa se um nó é acessível a partir de outro); 35

SECÇÃO 5.2 Exercícios propostos Implemente o tipo de dados grafo com listas de adjacência com os métodos acima descritos. 36

Proposta de resolução 1 public class GOMA { 2 int [][] MA; 3 4 public GOMA ( int dim ){ 5 MA=new int [ dim ][ dim ]; 6 } 7 8 public void adi_ aresta ( int i, int j) { 9 MA[i][j ]=1; 10 11 } 12 13 public void rem_ aaresta ( int i, int j) { 14 MA[i][j ]=0; 15 } 16 17 public boolean adjacenteq ( int i, int j) { 18 return MA[i][j ]==1; 19 } 20 21 private static int proxavisitar ( int [] v){ 22 int i=v. length -1; 23 while (i >=0 && v[i ]!=1) { 24 i - -; 25 } 26 return i; 37

27 } 28 29 public boolean acessivel ( int i, int j) { 30 int aux,next,v []= new int [MA. length ]; 31 v[i ]=1; 32 next = proxavisitar (v); 33 while ( next!= -1) { 34 if( next ==j) return true ; 35 v[ next ]=2; 36 aux =0; 37 while (aux <v. length ) { 38 if( adjacenteq (next, aux ) && v[ aux ]==0) v[ aux ]=1; 39 aux ++; 40 } 41 next = proxavisitar (v); 42 } 43 return false ; 44 } 45 46 public static void main ( String [] args ) { 47 GOMA g= new GOMA (3) ; 48 g. addaresta (1,0) ; 49 g. addaresta (0,1) ; 50 g. addaresta (2,1) ; 51 System. out. println (g. acessivel (0,2) ); 52 } 53 } 38

Prática 6 Pesquisa em profundidade em grafos Exercícios propostos para a aula SECÇÃO 6.1 1. Implemente o algoritmo Deep First Search baseado numa estrutura de pilha (LIFO); 2. Crie uma função que testa se um dado grafo é conexo ou não. 39

Proposta de resolução 1 public interface Tabela { 2 public void insere ( int i); 3 public void retira ( int i); 4 public boolean vazia (); 5 public boolean pesquisa ( int i); 6 } 1 public interface GrafoO { 2 public void addaresta ( int i, int j); 3 public void retiraaresta ( int i, int j); 4 public boolean adjacenteq ( int i, int j); 5 public int [] DFS ( int i); 6 public boolean conexo (); 7 } 1 public interface Pilha { 2 public void insere ( int i); 3 public boolean vazia (); 4 public void retira (); 5 public int ultimo (); 6 } 41

1 class Node { 2 int val ; 3 Node next ; 4 } 1 public class Pilhadyn implements Pilha { 2 3 protected Node first, last ; 4 5 public Pilhadyn (){ 6 first = null ; 7 last = null ; 8 } 9 10 public void insere ( int i) { /* insere no fim da lista */ 11 Node aux = new Node (); 12 aux. val =i; 13 aux. next = null ; 14 if( last!= null ){ 15 last. next = aux ; 16 last = aux ; 17 } else { 18 last = aux ; 19 first = aux ; 20 } 21 } 22 23 public boolean vazia () { 24 return first == null ; 25 } 26 27 public void retira () { /* retira o ultimo da lista */ 28 Node aux = first ; 29 if(aux == null ) return ; 42

30 if(aux. next == null ) { 31 first = null ; 32 last = null ; 33 } 34 else { 35 while ( aux. next!= last ) aux = aux. next ; 36 last = aux ; 37 aux. next = null ; 38 } 39 } 40 41 public int ultimo () { 42 if( last!= null ) return last. val ; 43 return -1; 44 } 45 46 public int primeiro () { 47 if( first!= null ) return first. val ; 48 return -1; 49 } 50 51 public FilaP copia (){ 52 FilaP n= new FilaP (); 53 Node aux = first ; 54 while ( aux!= null ){ 55 n. insere ( aux. val ); 56 aux = aux. next ; 57 } 58 return n; 59 } 60 } 1 public class GOLA implements GrafoO { 2 FilaP LA []; 43

3 4 public GOLA ( int dim ){ 5 LA=new FilaP [ dim ]; 6 int i =0; 7 while (i<dim ) { 8 LA[i]= new FilaP (); 9 i ++; 10 } 11 } 12 13 public void addaresta ( int i, int j) { 14 LA[i]. insere (j); 15 } 16 17 public void retiraaresta ( int i, int j) { 18 LA[i]. retira (j); 19 } 20 21 public boolean adjacenteq ( int i, int j) { 22 return LA[i]. pesquisa (j); 23 } 24 25 FilaP adjacentes ( int i) { 26 return LA[ i]. copia (); /* cria uma copia a arvore com raiz i */ 27 } 28 29 30 public int [] DFS ( int v) { 31 int numnos =LA. length ; 32 int [] order = new int [ numnos ]; 33 int [] visitados = new int [ numnos ]; 34 // 0 nao visitados, 1 colocados na lista w, 2 ja visitados 35 boolean b; 36 Pilhadyn w = new Pilhadyn (); 44

37 w. insere (v); 38 FilaP ladj ; /* lista de nos ( inteiros ) auxiliar */ 39 int i=0, cur_ord =0, nextno ; 40 while (i< numnos ) { visitados [i ]=0; i ++;} /* comeca por se por todos os valores a 0 indicando que nenhum vertice foi visitado */ 41 order [v]= cur_ord ; 42 while (!w. vazia ()) { 43 nextno =w. ultimo (); 44 w. retira (); 45 visitados [ nextno ] =2; 46 ladj = adjacentes ( nextno ); /* copia */ 47 cur_ ord ++; 48 order [ nextno ]= cur_ord ; 49 b= false ; 50 while (! ladj. vazia () &&!b) { 51 if( visitados [ ladj. ultimo () ]==0) { 52 w. insere ( ladj. ultimo ()); 53 visitados [ ladj. ultimo () ]=1; 54 b= true ; 55 } 56 ladj. retira (); 57 } 58 } 59 return order ; 60 } 61 62 public boolean conexo (){ 63 int [] order = new int [LA. length ]; 64 order = DFS (LA [0]. primeiro ()); 65 int i =0; 66 while (i< LA. length ){ 67 if ( order [i ]==0) return false ; 68 i ++; 69 } 70 return true ; 45

71 } 72 } 46