CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas – 2017

Slides:



Advertisements
Apresentações semelhantes
Listas encadeadas Prof. Rosana Palazon.
Advertisements

Listas duplamente encadeadas
Programação II Estruturas de Dados
David Menotti Algoritmos e Estruturas de Dados I DECOM – UFOP
David Menotti Estruturas de Dados I DECOM – UFOP
Estruturas de Dados I Prof.: Sergio Pacheco Prof.: Sergio Pacheco 1 1.
LINGUAGEM ESTRUTURADA TURBO C
Listas com Ponteiros Listas encadeadas Listas circulares.
Armazenamento de Dados em Arquivos
Slides: Prof. SIMÃO Revisão: Prof. João Fabro
Fundamentos de Programação 1
ALGORITMOS E ESTRUTURAS DE DADOS
exercícios listas encadeadas
Implementação de FILAS com Alocação Dinâmica
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
Árvore Binária de Busca
Estruturas de Dados Aula 15: Árvores
Prof. Alessandro Gonçalves
CES-10 INTRODUÇÃO À COMPUTAÇÃO Aulas Práticas – 2014 Capítulo X Encadeamento de Estruturas por Ponteiros.
Fundamentos de Programação 1 Slides 21 Prof.ª Fabiany e Prof. SIMÃO Linguagem C “Lista Encadeada”.
Fundamentos de Programação 1 Slides 18 Prof. SIMÃO Jean Marcelo SIMÃO Linguagem C “Arquivos Seqüências ou de Texto ”. 1.
1 Aula 06 – Funções Prof. Filipe Mutz Colocar mais exemplos de funções simples no começo.
Estrutura de Dados (DPADF 0056) Aula 7 – Encadeamento de Memória Universidade Federal de Santa Maria Colégio Agrícola de Frederico Westphalen Curso Superior.
Algoritmos e Programação utilizando Visualg
Estruturas de Dados Aula 2: Estruturas Estáticas
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas – 2017
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas – 2016
Introdução à Programação
Fundamentos de Programação 1
Estruturas de Decisão.
Capítulo II – Listas Lineares Gerais
Fundamentos de Programação 1
Estrutura de Dados Revisão
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas
INF1007 – Programação 2 9 – Pilhas
CES-11 ESTRUTURAS DE DADOS Aulas Práticas
FUNDAMENTO DE PROGRAMAÇÃO
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas
INF1007: Programação Funções Recursivas
Estrutura de dados Pilhas e filas
Fundamentos de Programação 1
FUNDAMENTO DE PROGRAMAÇÃO PROF. BRUNO DE CASTRO H. SILVA
FUNDAMENTO DE PROGRAMAÇÃO PROF. BRUNO DE CASTRO H. SILVA
Capítulo IV – Árvores Gerais
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas
Programação de Computadores I – Arquivos
Capítulo IV – Árvores Gerais
FUNDAMENTO DE PROGRAMAÇÃO PROF. WELLINGTON FRANCO
UNIDADE 7 Tipos estruturados
PROGRAMAÇÃO I UNIDADE 3.
Programação de Computadores I – Ponteiros
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas
Listas Encadeadas.
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas – 2017
Fundamentos de Programação 1
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS
Programação de Computadores I – Arquivos
Prof. Rafael Mesquita Pilha Prof. Rafael Mesquita
DHD – Desenvolvimento em Hardware
Fundamentos de Programação 1
Programação de Computadores I – Ponteiros
DHD – Desenvolvimento em Hardware
Continuação.
CES-41 COMPILADORES Aulas Práticas
Programação de Computadores LINGUAGEM C – AULA 03 – PROF. WELLINGTON TELLES.
DHD – Desenvolvimento em Hardware
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas – 2019
Aula 2 Professores: Conteúdo: Dante Corbucci Filho
Transcrição da apresentação:

CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas – 2017 Capítulo IV Árvores Binárias

O programa a ser desenvolvido neste capítulo irá: Montar a árvore binária para uma expressão aritmética Calcular o valor dessa expressão, percorrendo sua árvore em profundidade

Exemplo: 

O programa terá os seguintes passos principais: A expressão será digitada numa forma parentética apropriada A forma parentética será convertida em polonesa A polonesa será percorrida do final ao início, para a construção da árvore binária correspondente A árvore binária será percorrida para o cálculo de seu valor

Exemplo simples: Digitação da expressão em forma parentética: (((23 + 90) * (8 + (53 * 12))) + 42) Conversão de parentética para polonesa: 23 90 + 8 53 12 * + * 42 +

Construção da árvore binária a partir da polonesa: 23 90 + 8 53 12 * + * 42 + +

Construção da árvore binária a partir da polonesa: 23 90 + 8 53 12 * + * 42 + + 42

Construção da árvore binária a partir da polonesa: 23 90 + 8 53 12 * + * 42 + + * 42

Construção da árvore binária a partir da polonesa: 23 90 + 8 53 12 * + * 42 + + * 42 +

Construção da árvore binária a partir da polonesa: 23 90 + 8 53 12 * + * 42 + + * 42 + *

Construção da árvore binária a partir da polonesa: 23 90 + 8 53 12 * + * 42 + + * 42 + * 12

Construção da árvore binária a partir da polonesa: 23 90 + 8 53 12 * + * 42 + + * 42 + * 53 12

Construção da árvore binária a partir da polonesa: 23 90 + 8 53 12 * + * 42 + + * 42 + 8 * 53 12

Construção da árvore binária a partir da polonesa: 23 90 + 8 53 12 * + * 42 + + * 42 + + 8 * 53 12

Construção da árvore binária a partir da polonesa: 23 90 + 8 53 12 * + * 42 + + * 42 + + 90 8 * 53 12

Construção da árvore binária a partir da polonesa: 23 90 + 8 53 12 * + * 42 + + * 42 + + 23 90 8 * 53 12

Cálculo do valor da expressão na árvore binária: int ValExpressao (arvbin A) { caso a raiz de A seja: { número: retornar o valor do número; operador: caso o operador seja: { ‘+’: retornar ValExpressao (A->fesq) + ValExpressao (A->fdir); ‘*’: retornar ValExpressao (A->fesq) * }

(((n1 + n2) * (n3 + (n4 * n5))) + n6) Exercício 4.1: Obtenção dos átomos de uma expressão aritmética Sejam expressões do tipo: (((n1 + n2) * (n3 + (n4 * n5))) + n6) também chamadas expressões na forma parentética, onde ni é um número inteiro não negativo com um ou mais dígitos decimais os operadores são somente ‘+’ e ‘*’ todas as operações são colocadas entre parênteses

(((n1 + n2) * (n3 + (n4 * n5))) + n6) Átomos de uma expressão como essas são os seus números, seus operadores e seus parêntesis. Um átomo é uma entidade contendo dois campos: o tipo e um eventual atributo. Um átomo pode ser de um dos seguintes tipos: NUMERO: quando ele for um número inteiro OPERADOR: quando ele for um dos caracteres ‘+’ ou ‘*’ ABPAR: quando ele for o caractere ‘(’ FPAR: quando ele for o caractere ‘)’ INVAL: quando ele for qualquer outro caractere

(((n1 + n2) * (n3 + (n4 * n5))) + n6) O eventual atributo de um átomo depende de seu tipo: NUMERO: o atributo é o valor numérico do número OPERADOR: o atributo é o próprio caractere ‘+’ ou ‘*’ ABPAR: o átomo não precisa de atributo FPAR: o átomo também não precisa de atributo INVAL: o atributo é o próprio caractere Declarações para átomos: typedef struct atomo atomo; typedef union atribatomo atribatomo; union atribatomo { int valor; char oper, carac;}; struct atomo { int tipo; atribatomo atrib;};

Exemplo: átomos da expressão ((35 + 62) * 7) tipo ABPAR atrib - - - - - tipo ABPAR atrib - - - - - tipo NUMERO atrib / valor 35 tipo OPERADOR atrib / oper + tipo NUMERO atrib / valor 62 tipo FPAR atrib - - - - - tipo OPERADOR atrib / oper * tipo NUMERO atrib / valor 7 tipo FPAR atrib - - - - - typedef struct atomo atomo; typedef union atribatomo atribatomo; union atribatomo { int valor; char oper, carac;}; struct atomo { int tipo; atribatomo atrib;};

Trabalho a fazer: completar o esqueleto de programa a seguir que: Lê uma expressão na forma parentética Encontra seus átomos (tipos e atributos), guardando-os num vetor de átomos Escreve no vídeo o conteúdo desse vetor.

/* Biblioteca utilizada da linguagem */ #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <ctype.h> /* Constantes simbolicas gerais */ #define logic char #define TRUE 1 #define FALSE 0 /* Constantes simbolicas para os tipos dos atomos */ #define NUMERO 1 #define OPERADOR 2 #define ABPAR 3 #define FPAR 4 #define INVAL 5

Parentetica: vetor de átomos para armazenar os átomos da expressão /* Declaracoes de tipos */ typedef char expressao[100]; typedef struct atomo atomo; typedef union atribatomo atribatomo; union atribatomo {int valor; char oper, carac;}; struct atomo {int tipo; atribatomo atrib;}; /* Variaveis globais */ atomo Parentetica[100]; int nparent, i; char c; expressao expr; Parentetica: vetor de átomos para armazenar os átomos da expressão nparent: número atual de átomos em Parentetica expr: vetor de caracteres com a expressão i: cursor para percorrer expr c: guarda um caractere de expr

GetNonBlank: procura o próximo caractere não-branco em expr /* Prototipos das funcoes auxiliares */ void FormarAtomos (void); void EscreverAtomos (int, atomo[]); char GetNonBlank (void); char GetNext (void); void InicExpr (void); FormarAtomos: encontra todos os átomos de expr e os armazena em Parentetica EscreverAtomos: escreve na tela o conteúdo de todos os átomos em um vetor de átomos GetNonBlank: procura o próximo caractere não-branco em expr GetNext: retorna o próximo caractere de expr InicExpr: posiciona o cursor i no primeiro caractere de expr

/* Funcao main */ int main() { char c; printf ("Encontrar atomos de expressao? (s/n): "); do c = getche ( ); while (c!='s' && c!='n' && c!='S' && c!='N'); while (c == 's' || c == 'S') { clrscr (); printf ("Digite a expressao: "); setbuf (stdin, NULL); gets (expr); FormarAtomos (); printf ("\nAtomos da expressao:\n"); EscreverAtomos (nparent, Parentetica); printf ("\n\nEncontrar atomos de nova expressao? (s/n): "); } clrscr (); printf ("Fim das atividades!"); printf ("\n\n"); system ("pause"); return 0;

A função FormarAtomos poderá seguir as seguintes diretrizes: void FormarAtomos () { Zerar o número de átomos encontrados; Posicionar o cursor da expressão em seu início; Procurar o primeiro caractere não branco; enquanto esse caractere não for o ‘\0’ { Inserir um novo átomo em Parentetica, conforme o valor desse caractere; Caso seja dígito {- - - - -} Caso seja '+' ou '*' {- - - - -} Caso seja '(' ou ')' {- - - - -} Caso seja qualquer outro caractere {- - - - -} Acrescentar uma unidade ao número de átomos encontrados; Procurar o próximo caractere não branco; }

Caso seja dígito { Coletar os outros dígitos; O tipo do átomo é NUMERO; O atributo é o valor numérico da cadeia formada pelos dígitos coletados; } Caso seja '+' ou '*' { O tipo do átomo é OPERADOR; O atributo é o próprio caractere; Caso seja '(' ou ')' { O tipo do átomo é respectivamente ABPAR ou FPAR; O atributo não é necessário; Caso seja qualquer outro caractere { O tipo do átomo é INVAL;

Para uma expressão tal como ( ( 12 + 32 )*13 & + 43;) ) a função EscreverAtomos deverá mostrar na tela uma tabela semelhante à seguinte: Atomos da expressao:   TIPO | ATRIBUTO ----------------------- ABPAR | NUMERO | 12 OPERADOR | + NUMERO | 32 FPAR | OPERADOR | * NUMERO | 13 INVAL | & NUMERO | 43 INVAL | ;

/* Funcoes para percorrer a expressao */ char GetNonBlank ( ) { while (isspace (expr[i]) || (iscntrl (expr[i]) && expr[i] != '\0')) i++; return expr[i]; } char GetNext () { i++; void InicExpr ( ) { i = 0;

Exercício 4.2: Verificar se um vetor de átomos guarda a forma parentética de uma expressão, usando a seguinte definição recursiva: Sendo m e n dois números inteiros não negativos com um ou mais dígitos cada, (m + n) e (m * n) são expressões na forma parentética. Sendo α e β números inteiros não negativos ou expressões na forma parentética, (α + β) e (α * β) também são expressões nessa forma. É necessário adaptar essa definição a expressões compostas de átomos, conforme definido no exercício anterior.

Exercício 4.3: Transformar parentética em polonesa Obter um vetor de átomos correspondente à polonesa de uma expressão guardada num vetor de átomos, na forma parentética Exemplo: seja a seguinte forma parentética: (((23 + 90) * (8 + (53 * 12))) + 42) Sua polonesa correspondente: 23 90 + 8 53 12 * + * 42 +

Método de transformação: Percorrer o vetor da parentética; Ao encontrar um número, inseri-lo no final da polonesa Ao encontrar um operador, colocá-lo numa pilha de átomos; Ao encontrar um abre-parêntesis, nada fazer; Ao encontrar um fecha parêntesis, desempilhar um operador e colocá-lo no final da polonesa Sugestão: montar a polonesa durante o teste da parentética (Exercício 4.2)

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) Parentética Polonesa Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) Parentética Polonesa Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) Parentética Polonesa Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 Parentética Polonesa 23 Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 Parentética Polonesa 23 + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 Parentética Polonesa 23 90 + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + Parentética Polonesa 23 90 + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + Parentética Polonesa 23 90 + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + Parentética Polonesa 23 90 + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 Parentética Polonesa 23 90 + 8 * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 Parentética Polonesa 23 90 + 8 + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 Parentética Polonesa 23 90 + 8 + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 * Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 * + Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 * + * Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 * + * Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * 42 + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * 42 + Pilha de operadores

Declarações e protótipos para o TAD Pilha (estrutura encadeada): typedef struct noh noh; typedef noh *pilha; struct noh {atomo elem; noh *prox;}; void Empilhar (atomo, pilha*); void Desempilhar (pilha*); atomo Topo (pilha); void InicPilha (pilha*); logic Vazia (pilha);

Funções-operadores para o TAD Pilha (estrutura encadeada): void Empilhar (atomo x, pilha *P) { noh *temp; temp = *P; *P = (noh *) malloc (sizeof (noh)); (*P)->elem = x; (*P)->prox = temp;} void Desempilhar (pilha *P) { noh *temp; if (! Vazia(*P)) {temp = *P; *P = (*P)->prox; free (temp); } } atomo Topo (pilha P) {if (! Vazia(P)) return P->elem;} void InicPilha (pilha *P) { *P = NULL; } logic Vazia (pilha P) { if (P == NULL) return TRUE; else return FALSE; }

Exercício 4.4: Construir uma árvore binária para a expressão, a partir da polonesa Exemplo: Polonesa 23 90 + 8 53 12 * + * 42 + Árvore binária

Declarações para árvore binária: typedef struct celula celula; typedef celula *noharvbin; typedef celula *arvbin; struct celula {atomo elem; celula *pai, *fesq, *fdir;}; arvbin Arv; elem (atomo) pai fesq fdir celula Arv Árvore binária

Exercício 4.5: Escrever a forma parentética original da expressão, a partir da árvore binária Diretriz: percorrer a árvore binária em ordem-central, escrevendo os atributos dos nós e escrevendo parêntesis em momentos oportunos

Exercício 4.6: Calculo do valor da expressão na árvore binária: Diretrizes: int ValExpressao (arvbin A) { caso a raiz de A seja: { número: retornar o valor do número; operador: caso o operador seja: { ‘+’: retornar ValExpressao (A->fesq) + ValExpressao (A->fdir); ‘*’: retornar ValExpressao (A->fesq) * }

Exercício 4. 7: Estender o programa do Exercício 4 Exercício 4.7: Estender o programa do Exercício 4.6 para trabalhar com números reais Aceitar como número uma cadeia que comece com um ou mais dígitos, seguidos opcionalmente por um ponto e zero ou mais dígitos Exercício 4.8: Estender o programa do Exercício 4.7 para trabalhar com os operadores binários ‘-’ (subtração) e ‘/’ (divisão)

Exercício 4. 9: Estender o programa do Exercício 4 Exercício 4.9: Estender o programa do Exercício 4.8 para trabalhar com os seguintes operadores: ~: menos unário @: potenciação L: logaritmo R: raiz quadrada S: seno C: cosseno

Exemplos de expressões parentéticas e polonesas usando esses operadores: