• Nenhum resultado encontrado

AEDS-aula-estruturas-genericas

N/A
N/A
Protected

Academic year: 2021

Share "AEDS-aula-estruturas-genericas"

Copied!
22
0
0

Texto

(1)

Estruturas de Dados Genéricas

Leonardo Reis

Departamento de Computação e Sistemas Universidade Federal de Ouro Preto

(2)

Introdução

Para cada estrutura de dados (Lista, Fila, Pilha, . . . ) com tipos diferentes teremos que fazer uma nova implementação?

(3)

Introdução

O que altera de uma implementação para outra?

I Exemplo: Lista de int e Lista de Contatos

I Como mudam: interface do TAD, definição dos tipos e implementação das

funções?

Ideal: estrutura de dados que possa ser instanciada com qualquer tipo, sem necessidade de retrabalho (implementar novamente)!

1 s t r u c t lista { 2 i n t size; 3 s t r u c t node∗ head; 4 } ; 5 6 s t r u c t node { 7 Contato item; 8 s t r u c t node∗ next; 9 } ; 1 s t r u c t lista { 2 i n t size; 3 s t r u c t node∗ head; 4 } ; 5 6 s t r u c t node { 7 i n t item; 8 s t r u c t node∗ next; 9 } ;

(4)

Introdução

O que altera de uma implementação para outra?

I Exemplo: Lista de int e Lista de Contatos

I Como mudam: interface do TAD, definição dos tipos e implementação das

funções?

Ideal: estrutura de dados que possa ser instanciada com qualquer tipo, sem necessidade de retrabalho (implementar novamente)!

1 i n t l_pos(Lista l, Contato c) {

2 i n t i= 0;

3 s t r u c t node∗ aux= l−>head;

4 while(aux != NULL) {

5 i f(c_equals(aux−>item, c) )

6 return i; / / achou

1 i n t l_pos(ListaInt l, i n t e) {

2 i n t i = 0;

3 s t r u c t node∗ aux= l−>head;

4 while(aux != NULL) {

5 i f(aux−>item==e)

(5)

Introdução

O que altera de uma implementação para outra?

I Exemplo: Lista de int e Lista de Contatos

I Como mudam: interface do TAD, definição dos tipos e implementação das

funções?

Ideal: estrutura de dados que possa ser instanciada com qualquer tipo, sem necessidade de retrabalho (implementar novamente)!

1 i n t l_pos(Lista l, Contato c) {

2 i n t i= 0;

3 s t r u c t node∗ aux= l−>head;

4 while(aux != NULL) {

5 i f(c_equals(aux−>item, c) )

6 return i; / / achou 7 aux= aux−>next; i++;

8 }

9 return −1; / / não achou 10 }

1 i n t l_pos(ListaInt l, i n t e) {

2 i n t i = 0;

3 s t r u c t node∗ aux= l−>head;

4 while(aux != NULL) {

5 i f(aux−>item==e)

6 return i; / / achou 7 aux =aux−>next; i++;

8 }

9 return −1; / / não achou 10 }

(6)

Estruturas Genéricas em C

A linguagem Cnão prover mecanismos explícitospara definir tipos de dados genéricos, tais como as linguagens C++ e Java

Alternativa de Implementação em C:

I uso de ponteiros para qualquer informação (desconsidera o tipo):void*

I manipulação das informações usando funções fornecidas pelo usuário da

estrutura:ponteiros para funções

I cliente fica responsável por converter para o tipo específico

I desvantagem: perde-se a informação do tipo e fica mais propenso a erros

(7)

Ponteiros Para Funções

Declaração de ponteiros para funções:return_type (*var_name) (list_param)

I Exemplo: int (*pf) (int, int);

Inicialização de ponteiros de funções:var_name = func_name

I Exemplo: pf = soma; ou pf = &soma;

Uso de ponteiros de funções:var_name (list_param)

I Exemplo: pf(1,2)

Exemplo

1 i n t soma(i n t a, i n t b) { 2 return a+ b; 3 } 1 i n t main( ) { 2 i n t (∗pf) (i n t, i n t) ; 3 pf=soma; / / pf = &soma; 4 printf("%d \ n", pf(1 ,2) ) ; 5 return 0; 6 }

(8)

Estudo de Caso: Pilha Genérica

“transformar” a implementação de Pilha de inteiros em uma implementação genérica

modificar o tipo dos elementos armazenados para void* analisar cada função:

I se não acessa os dados armazenados, então não há o que modificar

I se acessa dados, então usar ponteiros de funções para prover acesso

(9)

Pilha Genérica: Definição do Tipo Estruturado

1 s t r u c t pilha { 2 i n t size; 3 s t r u c t node∗ top; 4 } ; 5 6 s t r u c t node { 7 i n t item; 8 s t r u c t node∗ next; 9 } ;

(10)

Pilha Genérica: Definição do Tipo Estruturado

1 s t r u c t pilha { 2 i n t size; 3 s t r u c t node∗ top; 4 } ; 5 6 s t r u c t node { 7 i n t item; 8 s t r u c t node∗ next; 9 } ; 1 s t r u c t pilha { 2 i n t size; 3 s t r u c t node∗ top; 4 } ; 5 6 s t r u c t node { 7 void∗ item; 8 s t r u c t node∗ next; 9 } ;

(11)

Pilha Genérica: Funções de Adição e Remoção

Item adicionado e removido é genérico

1 void s_push(PilhaInt s, i n t e) {

2 s t r u c t node∗ novo= (s t r u c t node∗)

3 malloc(sizeof(s t r u c t node) ) ;

4 novo−>item= e;

5 novo−>next= s−>top;

6 s−>top=novo; 7 s−>size++; 8 } 1 i n t s_pop(PilhaInt s) { 2 i f(s_isEmpty(s) ) 3 exit( 1 ) ; / / ERROR 4 s t r u c t node∗ n= s−>top; 5 i n t e= n−>item; 6 s−>top= n−>next; 7 free(n) ; 8 s−>size−−; 9 return e; 10 }

(12)

Pilha Genérica: Funções de Adição e Remoção

Funções modificadas:

1 void s_push(Pilha s, void∗ e) {

2 s t r u c t node∗ novo= (s t r u c t node∗)

3 malloc(sizeof(s t r u c t node) ) ;

4 novo−>item= e;

5 novo−>next= s−>top;

6 s−>top=novo;

7 s−>size++;

8 }

1 void∗ s_pop(Pilha s) {

2 i f(s_isEmpty(s) ) 3 exit( 1 ) ; / / ERROR 4 s t r u c t node∗ n= s−>top; 5 void∗ e= n−>item; 6 s−>top= n−>next; 7 free(n) ; 8 s−>size−−; 9 return e; 10 }

(13)

Pilha Genérica: Funções isEmpty e size

Adequar o nome do tipo

1 i n t s_isEmpty(PilhaInt s) { 2 return s−>size== 0 ? 1 : 0; 3 } 1 i n t s_size(PilhaInt s) { 2 return s−>size; 3 }

(14)

Pilha Genérica: Funções isEmpty e size

Funções modificadas: 1 i n t s_isEmpty(Pilha s) { 2 return s−>size== 0 ? 1 : 0; 3 } 1 i n t s_size(Pilha s) { 2 return s−>size; 3 }

(15)

Pilha Genérica: Funções de Criação e Remoção

Função de criação: adequar o nome do tipo

Função de remoção: liberar espaço do item na memória. Como? I função fornecida pelo usuário, como parâmetro

1 PilhaInt s_new( ) {

2 PilhaInt s = (PilhaInt)

3 malloc(sizeof(s t r u c t pilha) ) ;

4 s−>size= 0;

5 s−>top=NULL;

6 return s;

7 }

1 void n_free(s t r u c t node∗ n) {

2 i f(n ==NULL) 3 return; 4 n_free(n−>next) ; 5 free(n) ; 6 } 7

8 void s_free(PilhaInt s) {

9 n_free(s−>top) ;

10 free(s) ;

(16)

Pilha Genérica: Funções de Criação e Remoção

Função de criação: adequar o nome do tipo

Função de remoção: liberar espaço do item na memória. Como?

I função fornecida pelo usuário, como parâmetro

1 PilhaInt s_new( ) {

2 PilhaInt s = (PilhaInt)

3 malloc(sizeof(s t r u c t pilha) ) ;

4 s−>size= 0;

5 s−>top=NULL;

6 return s;

7 }

1 void n_free(s t r u c t node∗ n) {

2 i f(n ==NULL) 3 return; 4 n_free(n−>next) ; 5 free(n) ; 6 } 7

8 void s_free(PilhaInt s) {

(17)

Pilha Genérica: Funções de Criação e Remoção

Funções modificadas:

1 Pilha s_new( ) {

2 Pilha s = (Pilha)

3 malloc(sizeof(s t r u c t pilha) ) ;

4 s−>size= 0;

5 s−>top=NULL;

6 return s;

7 }

1 voidn_free(s t r u c t node∗ n,

2 void (∗fn) (void∗) ) { 3 i f(n==NULL) return; 4 n_free(n−>next, fn) ; 5 fn(n−>item) ; 6 free(n) ; 7 } 8

9 voids_free(Pilha s,

10 void (∗fn) (void∗) ) {

11 n_free(s−>top, fn) ;

12 free(s) ;

(18)

Pilha Genérica: Definição da Interface (TAD)

Adequar o nome do tipo: de PilhaInt para Pilha

Modificar as funções para receber / retornar o item genérico: void* Corrigir a assinatura das operações que precisam receber ponteiros de funções como parâmetros

1 # i f n d e f PILHAINT_H_INCLUDED

2 #define PILHAINT_H_INCLUDED

3

4 typedef s t r u c t pilha∗ PilhaInt;

5

6 PilhaInt s_new( ) ;

7 void s_free(PilhaInt) ;

8 void s_push(PilhaInt, i n t) ;

(19)

Pilha Genérica: Definição da Interface (TAD)

Definição atualizada:

1 # i f n d e f PILHA_H_INCLUDED

2 #define PILHA_H_INCLUDED

3

4 typedef s t r u c t pilha∗ Pilha;

5

6 Pilha s_new( ) ;

7 void s_free(Pilha, void (∗fn) (void∗) ) ;

8 void s_push(Pilha, void∗) ;

9 void∗ s_pop(Pilha) ;

10 i n t s_isEmpty(Pilha) ;

11 i n t s_size(Pilha) ;

12

(20)

Pilha Genérica: Pilha de Inteiros

1 #include " s t d i o . h"

2 #include " s t d l i b . h"

3 #include " Pilha . h"

4

5 void freeInt(void∗ e) {

6 i f(e ==NULL) return; 7 free(e) ; 8 } 9 10 i n t main( ) { 11 Pilha s=s_new( ) ; 12 i n t∗ item;

13 item=(i n t∗)malloc(sizeof(i n t) ) ;

14 ∗item= 5;

17 ∗item= 7;

18 s_push(s, item) ;

19 item=(i n t∗)malloc(sizeof(i n t) ) ;

20 ∗item= 3;

21 s_push(s, item) ;

22 item=(i n t∗)malloc(sizeof(i n t) ) ;

23 ∗item= 2; 24 s_push(s, item) ; 25 26 while(s_isEmpty(s) == 0) { 27 i n t∗ e= (i n t∗) s_pop(s) ; 28 printf("%d ", ∗e) ; 29 } 30 printf(" \ n") ;

(21)

Relembrando: TAD Contato

1 # i f n d e f CONTATO_H_INCLUDED

2 #define CONTATO_H_INCLUDED

3

4 typedef s t r u c t contato∗ Contato;

5

6 Contato c_new(char∗, char∗, char∗) ;

7 void c_free(Contato) ;

8 void c_print(Contato) ;

9 i n t c_equals(Contato, Contato) ;

10

11 char∗ c_getNome(Contato) ;

12 char∗ c_getSobreNome(Contato) ;

13 char∗ c_getFone(Contato) ;

14

15 void c_setNome(Contato, char∗) ;

16 void c_setSobreNome(Contato, char∗) ;

17 void c_setFone(Contato, char∗) ;

18

(22)

Pilha Genérica: Pilha de Contatos

1 #include " s t d i o . h" 2 #include " Contato . h" 3 #include " Pilha . h" 4 5 i n t main( ) { 6 Pilha s =s_new( ) ;

7 s_push(s, c_new(" Leonardo ", " Reis ", "9999−9999") ) ;

8 s_push(s, c_new("Emmanuel", " V i e i r a ", "8888−8888") ) ;

9 s_push(s, c_new(" Helen ", "da Silva ", "7777−7777") ) ;

10

11 while(s_isEmpty(s) == 0) {

12 Contato e = (Contato) s_pop(s) ;

13 printf("%s %s : %s \ n",c_getNome(e) , c_getSobreNome(e) , c_getFone(e) ) ;

Referências

Documentos relacionados

Quanto à atividade de produção legislativa, Rezende (2016) delimita ser exercida pelo que define como elites do poder, por ser exercida predominantemente por homens,

Constitui objeto do presente Edital a seleção e contratação de sociedade empresária especializada na execução de serviços de engenharia elétrica, visando a

O WANTED BUSINESS IDEAS é uma iniciativa de captação de novas ideias e negócios promovido e organizado pela Rede Regional de Empreendedorismo Viseu Dão Lafões, sob a coordenação da

Outros ativos intangíveis que são adquiridos pelo Grupo e que têm vidas úteis finitas são mensurados pelo custo, deduzido da amortização acumulada e das perdas por redução ao valor

Edital de Licitação CAIXA de Venda de Imóveis – Disputa Aberta 11.1 - O arrematante terá o prazo máximo de 05 (cinco) dias úteis, contado da data da divulgação

Deve ser obrigatório o uso do cinto de segurança tipo paraquedistas com talabarte fixado no trava quedas, com trava quedas fixadas na corda de segurança (de

Para análise da susceptibilidade à erosão dos solos que compunham as paredes da voçoroca, foram realizados ensaios de Pinhole (Furo de Agulha), Desagregação e Dispersão

Todos os anos o Observatório da Comunicação questiona um conjunto de stakeholders do sector da comunicação e solicita avaliações do ano que terminou e previsões para o ano que se