- estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é...

75
1 - Estruturas e aplicações MCTA028 – Programação Estruturada Luiz Rozante 3Q-2018 Material preparado a partir de slides dos profs. Jesús Mena-Chalco e Fabrício Olivetti

Upload: lecong

Post on 27-Jan-2019

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

1

- Estruturas e aplicações

MCTA028 – Programação Estruturada

Luiz Rozante

3Q-2018

Material preparado a partir de slides dos profs. Jesús Mena-Chalco e Fabrício Olivetti

Page 2: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

2

Estruturas (=registros)

Page 3: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

3

Linguagem C: Tipos de dados

Tipos de dados primários.Tipos de dados derivados.Tipos definidos pelo usuário.

(*) Fonte: http://www.studytonight.com/c/datatype-in-c.php

Page 4: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Para definir e usar um tipo de usuário

Definição

Declaração

Acesso

Em C, structs permitem definir tipos de dados como umacomposição de tipos já existentes.

O uso de tipos de usuário exige três “passos”:

Page 5: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Definição de tipo de usuário

Podemos definir (“dizer como é”) um tipo novo usando tipos já existentes (definidos ou pré-definidos).

Forma geral:

struct nome_tipo { nome_tipo_1 nome_membro_1; nome_tipo_2 nome_membro_2; ... nome_tipo_k nome_membro_k; };

Page 6: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Declaração de variáveis de tipo de usuário

Declaramos uma variável de tipo definido (de usuário) da mesma forma que declaramos uma de tipo pré-definido.

struct nome_tipo nome_var;

Page 7: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Definição e declaração de tipos de usuário com a cláusula typedef (redefinidor de nomes de tipo).

Forma geral:

typedef struct {

nome_tipo_1 nome_membro_1;

nome_tipo_2 nome_membro_2;

...

nome_tipo_k nome_membro_k;

}nome_tipo_novo;

nome_tipo_novo nome_var;

definição

declaração

Page 8: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Acesso a variáveis de tipo de usuário

O acesso aos membros (campos) de variáveis declaradas a partir de tipo de usuário (definido) é feito através do operador de acesso:

– ponto (´.´), – seta (' -> '), se ponteiro para estrutura (registro).

Page 9: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

9

Estruturas

Page 10: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

1. #include <stdio.h>2.3. struct ALUNO { //Definição da estrutura4. float nota;5. int cod;6. char conceito;7. };

1. void main() {2. int i;3. struct ALUNO jose, ana; // Declara variáveis4. struct ALUNO turma[7]; // do tipo ALUNO5. jose.nota = 7.0; // Acessa membros da6. jose.cod = 1212; // variável jose7. if (jose.nota < 7.0) { 8. jose.conceito = ‘R’; 9. } 10. else {11. jose.conceito = ‘A’; 12. }13. 14. for (i=0 ; i<=6 ; i++) {15. turma[i].cod = 100 + i; • turma[i].nota = 0.0;1. }2. }

Page 11: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

1. #include <stdio.h>2. struct FICHA { //Definição da estrutura FICHA3. char nome[40];4. int cod;5. float salario;6. };

1. void le_cadastro();

1. /* declara um vetor tipo FICHA */ 2. struct FICHA cadastro[100];

1. void main() { le_cadastro(); }

1. void le_cadastro() {2. int i;3. for (i=0 ; i<=99 ; i++) {4. printf(“Nome = “);5. gets(cadastro[i].nome);6. printf(“\n “);7. printf(“Código = “);8. scanf(“%d\n”, &cadastro[i].cod);• printf(“\n “);1. printf(“Salário = “);• scanf(“%f\n”, &cadastro[i].salario);1. }2. }

1)

Page 12: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

1. #include <stdio.h>2. #include <conio.h>3. struct DATA { //Definição da estrutura DATA4. int dia;5. char mes[10];6. int ano;7. };

1. struct VENDA { //Definição da estrutura VENDA 2. int cod;3. int qtde;4. float preco;5. struct DATA dt_venda;6. };

1. void impr_venda();2. void impr_vendaS();

1. /* inicialização da variável x tipo VENDA */2. struct VENDA x={12,10,23.4,{5,”Mar”,2002}};

1. /* declaração de uma matriz tipo VENDA */2. struct VENDA reg_venda[1000];

1. void main() {2. impr_venda();3. impr_vendaS();4. }

2)

Page 13: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

24. void impr_venda() {25. printf(“Cod= %d\n”, x.cod);26. printf(“Qtde= %d\n”, x.qtde);27. printf(“Preço= %f\n”, x.preco);28. printf(“Data da venda = %d/%s/%d ”,29. x.dt_venda.dia, 30. x.dt_venda.mes, 31. x.dt_venda.ano);32. }

24. void impr_vendaS() {25. int i;26. for (i=0 ; i<=999 ; i++) {27. printf(“Cod = %d\n”,reg_venda[i].cod);28. printf(“Qtde= %d\n”,reg_venda[i].qtde);29. printf(“Preço=%f\n”,reg_venda[i].preco);30. printf(“Data da venda = %d/%s/%d ”,31. reg_venda[i].dt_venda.dia, 32. reg_venda[i].dt_venda.mes, 33. reg_venda[i].dt_venda.ano);34. }35. }

2)

Page 14: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

14

Estruturas

Operador de acesso indireto

Page 15: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Tipos abstratos de dados (TAD)

Para resolver um problema é necessário escolher uma abstração da realidade, em geral mediante a definição de um conjunto de dados que representa a situação real

A seguir, deve ser escolhida a forma de representar esses dados

A escolha da representação dos dados é determinada, entre outras, pelas operações a serem realizadas sobre os dados

15

Page 16: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Exemplo de TAD: Listas Lineares ● Sequência de zero ou mais itens x1, x2, ... , xn, na qual

xi é de um determinado tipo e n representa o tamanho da lista linear

● Sua principal propriedade estrutural envolve as posições relativas dos itens em uma dimensão

– Assumindo n >= 1, x1 é o primeiro item da lista e xn é o último item da lista

– xi precede xi+1 para i = 1, 2, . . ., n – 1– xi sucede xi-1 para i = 2, 3, . . ., n – o elemento xi é dito estar na i-ésima posição da lista

16

Page 17: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Listas Lineares

● Muitas aplicações

● Principal aplicação: representação interna de conjuntos.

17

Page 18: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Listas Lineares: Implementações

● Pode ser implementada de diferentes maneiras– Estática

● todo o espaço de memória a ser utilizado (para armazenar os itens) é reservado (alocado) no início da execução do programa ou módulo

● esse espaço de memória permanece reservado durante toda a execução do programa, independente de estar sendo efetivamente utilizado ou não

– Dinâmica● o espaço de memória a ser utilizado (para armazenar

os itens) pode ser reservado (alocado) no decorrer da execução de um programa ou módulo, quando for efetivamente necessário

● o espaço reservado pode ser liberado durante a execução do programa, quando não for mais necessário

18

Page 19: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Listas Lineares - Estática

● Podem dispor os seus elementos de maneira

– Seqüencial: os itens ficam, necessariamente, em sequência (um ao lado do outro) na memória

– Encadeada: os itens não estão, necessariamente, em posições de memória adjacentes (sequência lógica ou virtual)

19

Page 20: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Listas Lineares – Estática Seqüencial● Os itens da lista são armazenados

em posições contíguas de memória● A lista pode ser percorrida em

qualquer direção● A inserção de um novo item pode ser

realizada após o último item com custo constante O(1)

● A inserção de um novo item no meio da lista requer um deslocamento de todos os itens localizados após o ponto de inserção O(n)

● Retirar um item do início da lista requer um deslocamento de itens para preencher o espaço deixado vazio O(n)

20

ItensÍndices

X1

X2

Xn

MaxTam

1

2

n

.

.

.

.

.

.

Page 21: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Listas Lineares – Estática Seqüencial (TAD)

● Para a definição de um TAD, o conjunto de operações a ser definido depende de cada aplicação

● Exemplos:– 1. Criar uma lista linear vazia– 2. Inserir um novo item imediatamente após o i-ésimo item– 3. Retirar o i-ésimo item– 4. Localizar o i-ésimo item para examinar e/ou alterar o

conteúdo de seus componentes.– 5. Combinar duas ou mais listas lineares em uma lista única– 6. Partir uma lista linear em duas ou mais listas– 7. Fazer uma cópia da lista linear– 8. Ordenar os itens da lista em ordem ascendente ou

descendente, de acordo com alguns de seus componentes– 9. Pesquisar a ocorrência de um item com um valor

particular em algum componente21

Page 22: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Listas Lineares – Estática SeqüencialVantagens/Desvantagens

● Vantagens– acesso direto indexado a qualquer elemento da lista – tempo constante para acessar o i-ésimo item - dependerá

somente do índice

● Desvantagens – movimentação quando o item é eliminado/inserido– tamanho máximo pré-estimado

● Diante disso, quando usar?– listas pequenas – inserção/remoção no fim da lista – tamanho máximo bem definido

22

Page 23: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

MC-1424 Algoritmos e Estruturas de Dados I - 2° trimestre de 2009

Listas Lineares – Estática Seqüencial Programa em C

#include <stdio.h>

#include <stdlib.h>

#define TAM_MAX 5

#define NULO -9999999

int insere (int lista[], int *n, int chave);

int remove_final (int lista[], int *n);

int remove_inicio (int lista[], int *n);

int imprime (int lista[], int n);

char menu(void);

main()

{

int lista[TAM_MAX];

int num_atual = 0;

...

}

23

Page 24: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Listas Lineares – Estática Seqüencial Função: Inserir no final

int insere (int lista[], int *n, int chave)

{

if (*n == TAM_MAX) return (NULO);

lista[(*n)++] = chave;

return (0);

}

24

Page 25: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Listas Lineares – Estática Seqüencial Função: Remover do final

int remove_final (int lista[], int *n){ if (*n == 0) return (NULO); return (lista[--(*n)]);}

25

Page 26: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Listas Lineares – Estática Seqüencial Função: Remover do início

int remove_inicio (int lista[], int *n){ int i, primeiro; if (*n == 0) return (NULO); primeiro = lista[0]; for (i=1; i < *n; i++) lista[i-1]= lista[i]; (*n)--; return primeiro;} Complexidade: (?)

26

Page 27: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Listas Lineares – Estática Seqüencial Função: Imprimir lista

int imprime (int lista[], int n){ int i; if (n == 0) printf ("Lista vazia!\n"); else { printf ("%d elementos na lista\n", n); for (i=0; i < n; i++) printf ("Elemento %d = %d\n", i+1, lista[i]);

} return (0);}

27

Page 28: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Listas Lineares – Estática Seqüencial Função: Busca lista

Exercício: Como seria a função de busca na lista ?

28

Page 29: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Listas Lineares – Estática Seqüencial Função: Busca lista

Exercício: Como seria a função de busca na lista ?

int busca (int lista[], int n, int chave){int i, achou = 0;

if (n == 0) return(achou); else { for(i = 0;i < n; i++){ if(lista[i] == chave) achou = 1; } return (achou);}

29

Page 30: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Algumas implementações possíveis

● Na forma Dinâmica como ponteiros de nós, a lista pode ser implementada de várias formas, por exemplo:

– Lista Encadeada Simples

– Lista com Descritor

– Lista Duplamente Encadeada

30

Page 31: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Lista Dinâmica Encadeada● Numa lista encadeada, um espaço de memória é alocado para cada

novo elemento (item) inserido na estrutura– O espaço total de memória é proporcional ao número de

elementos– Não há garantia de que os elementos da lista ocuparão espaço de

memória contíguo não há acesso direto aos elementos● Para percorrer todos os elementos da lista é necessário guardar o

seu encadeamento– Armazena-se, junto com a informação de cada elemento, um

ponteiro para o próximo elemento da lista

31

Info1 Info2 Info3

Prim

NULL

Page 32: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Lista Dinâmica Encadeada

32

● Os itens da lista são nós com um dos componentes destinado a guardar o endereço do nó sucessor

● Ex: L = anta, cabra, gato, pato, rato

● onde cada nó é:

– Diz-se que cada nó aponta para o próximo nó– O próximo do último nó é um apontador para NULL– É necessário um apontador para o primeiro nó da lista

Page 33: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Lista Dinâmica Encadeada Estrutura auto-referenciada

33

● Exemplo: o nó de uma lista para armazenar números inteiros pode ser representado em C

struct {

int info;

struct no *proximo;

}no;

● Estrutura auto-referenciada possui um campo que é um ponteiro para uma próxima estrutura do mesmo tipo

● Essa estrutura representa um nó da lista, e a estrutura de lista encadeada é representada pelo ponteiro para o primeiro elemento

Page 34: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Lista Dinâmica Encadeada TAD

● Para a definição de um TAD, o conjunto de operações a ser definido depende de cada aplicação

● Exemplos:– 1. Criar uma lista vazia– 2. Verificar se a lista está vazia– 3. Inserir um novo item no início da lista– 4. Inserir um novo item no final da lista– 5. Retirar um item da lista no começo– 6. Retirar um item da lista no fim– 7. Buscar um item na lista– 8. Imprimir os itens da lista– 9. Determinar o comprimento da lista– 10. Liberar a lista– ...

34

Page 35: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Lista Dinâmica Encadeada Simples Análise de algumas operações

● Função de inserção no início da lista– Para cada elemento inserido é necessário alocar dinamicamente

a memória necessária– Nota importante: o ponteiro que representa a lista deve ter seu

valor atualizado

35

Info1 Info2 Info3

Prim

NULL

Novo

Page 36: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Lista Dinâmica Encadeada Simples Análise de algumas operações

● Função que retira um elemento da lista– Duas situações tem que ser consideradas

● (a) Remoção no início da lista● (b) Remoção no “meio“ da lista

36

Info1 Info2 Info3

Prim

NULL

Info1 Info2 Info3

Prim

NULL

(a)

(b)

Page 37: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Lista encadeada (código): tipos e ponteiros

1. #include <stdio.h>2. #include <stdlib.h>

3. typedef struct {4. int valor;5. struct nodo *prox;6. }nodo;

7. nodo *prim;8. nodo *p;9. nodo *q;

10. void cria_lista_vazia();11. void verifica_se_lista_vazia();12. void inclui_inicio(int x);13. void inclui_fim(int x);14. void imprime_lista();15. void remove_inicio();16. void remove_fim();

Page 38: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Código: main

1. int main(int argc, char** argv) {2. cria_lista_vazia();3. printf("\n");4. verifica_se_lista_vazia();5. inclui_inicio(10);6. inclui_inicio(12);7. inclui_fim(30);8. inclui_fim(40);9. remove_inicio();10. remove_fim();11. imprime_lista();12. return (EXIT_SUCCESS);13.}

Page 39: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Código: cria lista vazia

1. void cria_lista_vazia(){

2. prim = NULL;

3. printf("criei lista vazia\n");

4. }

Page 40: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Código: verifica se é vazia

1. void verifica_se_lista_vazia(){2. if (prim == NULL){3. printf("a lista está lista vazia\n");4. printf("prim = %p \n", prim);5. }6. else {7. printf("a lista NÃO está vazia");8. printf("prim = %p \n", prim);9. }10.}

Page 41: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Código: inserir no início

1. void inclui_inicio(int x){

2. if ((p = (struct nodo*) malloc(sizeof(nodo))) == NULL) {3. printf(" nao consegui alocar memoria para p\n");4. exit(0);5. }

6. p->prox = prim;7. p->valor = x;8. prim = p;9. }

Page 42: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Código: inserir no fim

1. void inclui_fim(int x){

2. if ((p = (struct nodo*) malloc(sizeof(nodo))) == NULL) {3. printf(" nao consegui alocar memoria para p\n");4. exit(0);5. }

6. q = prim;7. while (q->prox != NULL){8. q = q->prox;9. }

10. p->valor = x;11. q->prox = p;12. p->prox = NULL;

13.}

Page 43: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Código: excluir no começo

1. void remove_inicio(){

2. p = prim->prox;

3. free(prim);

4. prim = p;

5. }

Page 44: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Código: excluir no fim

1. void remove_fim(){2. q = prim->prox;3. while (q->prox != NULL){4. p = q;5. q = q->prox;6. }7. free(q);8. p->prox = NULL;9. }

Page 45: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Código: imprimir

1. void imprime_lista(){2. p = prim;3. do {4. printf(" %d ", p->valor);5. p = p->prox;6. }while (p->prox != NULL);7. printf(" %d ", p->valor);8. printf("\n");

9. }

Page 46: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Comparação entre as estratégiasEstática Seqüencial vs. Dinâmica Encadeada

46

● Quando é melhor utilizar uma implementação ou outra?

– Principais características que devem ser consideradas● A implementação estática (array) requer a

especificação do tamanho máximo da lista em tempo de compilação. Se não for possível especificar o tamanho máximo que a lista pode atingir, seria mais adequado escolher a implementação dinâmica

● A implementação estática pode desperdiçar espaço. A implementação dinâmica requer espaço para os ponteiros em cada célula. Em diferentes circunstâncias um método pode acabar utilizando mais espaço do que o outro

Page 47: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Comparação entre as estratégiasEstática Seqüencial vs. Dinâmica Encadeada

47

● Quando é melhor utilizar uma implementação ou outra?

– Principais características que devem ser consideradas● Algumas operações são mais custosas em uma

implementação e não na outra

– Inserção e deleção no início tempo constante na implementação dinâmica encadeada, mas tempo proporcional ao número de elementos na implementação estática

– No final tempo constante na implementação estática, mas tempo proporcional ao número de elementos na implementação dinâmica encadeada

Page 48: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Lista Dinâmica Encadeada Alguns Problemas

● Caracteriza-se por formar um encadeamento simples entre os elementos– Cada elemento armazena um ponteiro para o próximo elemento

da lista● Problemas dessa estratégia

– Não temos como percorrer a lista em ordem inversa de maneira eficiente

– Dificulta a retirada de um elemento da lista. Mesmo se tivermos o ponteiro para o elemento que se deseja retirar, temos que percorrer a lista para encontrar o elemento anterior

● Solução– Lista com descritor?– Lista Dinâmica Duplamente Encadeada

48

Page 49: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Outro exemplo de TAD: Pilhas

49

Page 50: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Pilhas

É a estrutura de dados mais utilizada em programação, sendo inclusive implementada diretamente pelo hardware da maioria das máquinas modernas

A idéia fundamental da pilha é que todo o acesso a seus elementos é feito por meio do seu topo

É um conceito semelhante a qualquer tipo de pilha: pratos, livros, CDs, etc

50

Page 51: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Pilhas (Stacks)

Estrutura de dados com a característica LIFO

LIFO: Last-In First-Out

O último a entrar é o primeiro a sair

Funcionamento

O primeiro item inserido na pilha fica no fundo, sendo o último a ser removido

Todos os itens inseridos na pilha são colocados em cima dos itens anteriores

O último item inserido na pilha é o que está no topo, sendo topo, sendo o primeiro a ser removido

51

Page 52: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Pilhas (Stacks)

Para que serve? Para modelar situações em que é preciso “guardar

para mais tarde” vários elementos, e “lembrar” sempre do último elemento armazenado (LIFO)

52

Page 53: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Pilhas (animação)

53MC-1424 Algoritmos e Estruturas de Dados I - 2° trimestre de 2009http://www.cosc.canterbury.ac.nz/people/mukundan/dsal/StackAppl.html

Page 54: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Características de Pilhas

Dados somente podem ser colocados no topo da pilha

Dados somente podem ser removidos do topo da pilha

Dados somente podem ser removidos do fundo da pilha se existe somente um elemento na pilha

Dados não podem ser removidos do meio da pilha sem antes remover todos os itens anteriores (do topo)

54

Page 55: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Operações de uma Pilha

Principais

Empilha (push) Desempilha (pop)

Auxiliares

Topo (peek) Vazia (isEmpty) Cheia (isFull) Procura (search)

55

Page 56: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Implementação de Pilhas

Lista Estática Seqüencial (Array)

Fácil de implementar Tamanho limitado

Lista Dinâmica Encadeada

Implementação mais complexa Sem limitação de tamanho (memória do

computador) Memória alocada dinamicamente Listas encadeadas que se insere e remove do início

são pilhas

56

Page 57: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Pilha em Lista Estática Seqüencial

PILHA - lista estática seqüencial que implementa pilha o elemento 0 será definido como o fundo da pilha topo da pilha: TOPO é o índice que indica a 1a. posição

livre da pilha Ppilha vazia: TOPO = 0 restrição: tamanho máximo

1o. elem.

2o. elem.

3o. elem.

4o. elem.

3

57

3

2

1

0

Page 58: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Pilha em C – Exemplo (1)

#define MAX 50

typedef struct pilha {

int n;

int vet[MAX];

} tipoPilha;

// Prototipos das funcoes

tipoPilha *cria(void);

void push(tipoPilha *p, int v),

libera(tipoPilha *p);

int pop(tipoPilha *p),

vazia(tipoPilha *p);

58

Page 59: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

MC-1424 Algoritmos e Estruturas de Dados I - 2° trimestre de 2009

Pilha em C – Exemplo (1)// Funcao para criar uma pilha de dadostipoPilha *cria(void){tipoPilha *p = (tipoPilha*) malloc(sizeof(tipoPilha));p->n = 0; // Inicializa pilha com zero elementosreturn p;

}

// empilhamento (push) de elementosvoid push(tipoPilha *p, int v){if (p->n == MAX) {printf("Capacidade da pilha estourou.\n");exit(1);}/*Insere elemento na proxima posicao livre*/p->vet[p->n] = v;p->n++;

}

59

Page 60: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

60MC-1424 Algoritmos e Estruturas de Dados I - 2° trimestre de 2009

Pilha em C – Exemplo (1)// Funcao para desempilhamento (pop) de elementosint pop(tipoPilha *p){int v;if (vazia(p)) {printf("tipoPilha vazia.\n");return -1;}v = p->vet[p->n-1];p->n--;return v;

}// Funcao que verifica se uma pilha esta vaziaint vazia(tipoPilha *p){return (p->n == 0);

}

Page 61: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Pilha em C – Exemplo (1)

/* Funcao que libera espaco em memoria alocado para a pilha */

void libera(tipoPilha *p){free(p);

}

61

Page 62: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Topo – agora é um ponteiro para o topo da pilha Pilha vazia: Topo= NULL

não possui restrição de tamanho máximo

Pilhas em lista encadeada

62

Page 63: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Pilha em lista encadeada

empilha

desempilhanovo elemento

63

Page 64: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Aplicações de Pilhas

Aplicações diretas Histórico de páginas visitadas em um navegador

Web Desfazer uma seqüência de ações em um editor de

textos (Ctrl+Z) Realizar cálculos usando a notação polonesa (por

exemplo, calculadoras HP) Chamada de procedimentos em Sistemas

Operacionais

Aplicações indiretas Estrutura de dados auxiliar para algoritmo

64

Page 65: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Exemplo de aplicação

Calculadora pós-fixada

Notação para expressões aritméticas – infixa = operador entre os operandos (1-2)*(4+5)

pós-fixa = operador após operandos 1 2 – 4 5 + * pré-fixa = operador antes dos operandos * - 1 2 + 4 5

Exemplo:

calculadora HP científica usa notação pós-fixa

65

Page 66: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Exemplo de aplicação

Calculadora pós-fixada

Avaliação de expressões aritméticas pós-fixadas: cada operando é empilhado numa pilha de valores quando se encontra um operador desempilha-se o número apropriado de operandos realiza-se a operação devida empilha-se o resultado

Exemplo: avaliação da expressão 1 2 – 4 5 + * Tipo de dados abstratos (TDA)

66

Page 67: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Tipos abstratos de dados (TAD)

A idéia é encapsular (esconder) de quem usa um determinado tipo a forma concreta com que ele foi implementado

Para isso, separa-se a declaração e a implementação do TAD em dois arquivos:

- NomeDoTAD.h : com a declaração

- NomeDoTAD.c : com a implementação

O programa ou outros TADs que utilizam o seu TAD devem dar um #include no arquivo .h

67

Page 68: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Tipos abstratos de dados (TAD)

Exemplo:

Vamos implementar a estrutura de um TAD em ContaBancaria, com os campos número e saldo onde os clientes podem fazer as seguintes operações:

• Iniciar uma conta com um número e saldo inicial

• Depositar um valor

• Sacar um valor

• Imprimir o saldo

68

Page 69: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Tipos abstratos de dados (TAD)

ContaBancaria.h

/* definição do tipo */typedef struct { int numero; double saldo;} ContaBancaria;

/* declaração das funções */void Inicializa(ContaBancaria* conta, int numero, double saldo);

void Deposito (ContaBancaria* conta, double valor);

void Saque (ContaBancaria* conta, double valor);

void Imprime (ContaBancaria conta);

69

Page 70: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

MC-1424 Algoritmos e Estruturas de Dados I - 2° trimestre de 2009

Tipos abstratos de dados (TAD)ContaBancaria.c

#include <stdio.h>#include "Contabancaria.h"void Inicializa(ContaBancaria* conta, int numero, double saldo){ (*conta).numero = numero; (*conta).saldo = saldo;}void Deposito (ContaBancaria* conta, double valor){ (*conta).saldo += valor;}void Saque (ContaBancaria* conta, double valor){ (*conta).saldo -= valor;}void Imprime (ContaBancaria conta){printf("Numero: %d\n", conta.numero);printf("Saldo: %f\n", conta.saldo);}

70

Page 71: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Tipos abstratos de dados (TAD)

int main (int argc, char **argv){ ContaBancaria conta1; Inicializa(&conta1, 918556, 300.00); printf("\nAntes da movimentacao:\n "); Imprime(conta1); Deposito(&conta1, 50.00); Saque(&conta1, 70.00); printf("\nDepois da movimentacao:\n "); Imprime (conta1);}

71

Page 72: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

72

Atividade em aula

Implementar uma TAD para pilha em lista encadeada com as seguintes operações :

1. Criar uma pilha vazia2. Empilhamento3. Desempilhamento4. Imprime a pilha

Page 73: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

73

Page 74: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

Pilha em C (arquivo pilha.h) – Ex2

typedef struct {int matricula;char nome[20];

} t_pilha;

void empilha(t_pilha aluno);t_pilha desempilha();t_pilha noTopo();int cheia();int vazia();

74

Page 75: - Estruturas e aplicaçõesprofessor.ufabc.edu.br/~g.mota/courses/programacao_estruturada... · é feito através do operador de acesso: – ponto (´.´), – seta ... descendente,

MC-1424 Algoritmos e Estruturas de Dados I - 2° trimestre de 2009

Pilha em C (arquivo pilha.c) –Ex2#include "pilha.h“

#define TAMMAX 3

#define VAZIA -1

int topo = VAZIA;

t_pilha pilha[TAMMAX];

void empilha(t_pilha aluno){

pilha[++topo] = aluno;

}

t_pilha desempilha() {

return pilha[topo--];

}

t_pilha noTopo() { return pilha[topo];}

int cheia() { return topo+1 == TAMMAX;

}

int vazia() { return topo == VAZIA;

}75