• Nenhum resultado encontrado

Apostila 02 Conceito de Pilha em ED

N/A
N/A
Protected

Academic year: 2021

Share "Apostila 02 Conceito de Pilha em ED"

Copied!
11
0
0

Texto

(1)

Curso: Bacharelado em Ciência da Computação -

BCC

Disciplina: (1479A) Estruturas de Dados I – ED1 Professora: Simone das Graças Domingues Prado e-mail: [email protected]

home-page: wwwp.fc.unesp.br/~simonedp/ed1bcc.htm

Apostila 02 – Conceito de Pilha em ED

Objetivos:

⇒ Conceituar tipo abstrato de dados pilha ⇒ Conhecer e implementar vários tipos pilhas ⇒ Trabalhar com pilhas estáticas

⇒ Trabalhar com pilhas dinâmicas

Conteúdo:

1. Introdução 2. Pilhas estáticas

2.1. Primeira definição de Pilhas Estáticas 2.2. Segunda definição de Pilhas Estáticas

3. Pilhas usando Lista Linear Simplesmente Encadeada

4. Pilhas usando Lista Linear Simplesmente Encadeada com Descritor 5. Exercícios

(2)

1. Introdução

Vários tipos de listas já foram estudados. Percebe-se que, nas listas, o acesso era feito sem nenhuma restrição. Podia-se inserir e remover elementos em qualquer posição, só dependendo se a lista era ordenada ou não.

As Pilhas e as Filas são listas que possuem critérios de acessos restritivos. Vejamos os critérios de acesso mais usuais:

FIFO - (First Input, First Output) ou seja, o primeiro que entrar é o primeiro a sair.

LIFO - (Last Input, First Output) ou seja, o último que entrar numa lista é o primeiro a sair dela

Levando em consideração esses critérios de acesso e pelo que se conhece, informalmente, por pilha e fila pode-se identificar que uma Pilha é uma lista que tem como critério de acesso o LIFO, e a fila, o FIFO.

Dessa forma, uma Pilha é um conjunto de elementos no qual novos itens podem ser inseridos ou removidos em uma única extremidade, a qual é chamada de topo. A pilha possuirá características bem próprias de acesso e por conseqüência terá operações bem simples de empilhar e desempilhar elementos.

Veja a figura a seguir onde se têm quatro peças para empilhadas rotuladas como A, B, C e D. Para a pilha abaixo ficar com essa configuração deve-se colocar primeiro a peça A, depois a B, C e D. e se for retirar só conseguiremos tirar na ordem: D, C, B e A

A manipulação de uma pilha pode ser feita de forma estática ou dinâmica. A forma estática usará variável do tipo matriz e as pilhas dinâmicas usarão ponteiros. Numa pilha estática tem-se que preocupar com o tamanho da pilha, já que a alocação da variável é feita de forma estática. Assim, ao inserir um elemento tem-se de verificar se a pilha comporta. Na pilha dinâmica (que usa ponteiros) ao inserir o elemento tem-se de verificar se existe memória para a criação de um novo elemento na pilha.

2. Pilhas estáticas

Na implementação de pilhas estáticas pode surgir várias formas de construção do tipo de dado pilha. Veja aqui duas definições: uma definição usará um vetor e variável topo separadas e a outra definição usará uma estrutura que conterá o vetor e o topo.

Independente de qual seja a construção do tipo pilha, deve-se preocupar com as operações básicas de: • verificação de pilha vazia (se estiver vazia, não se pode tentar desempilhar elementos)

• verificação de pilha cheia (se estiver cheia, não se pode empilhar elementos) • empilhar um elemento na pilha sem ultrapassar o tamanho do vetor

• desempilhar um elemento da pilha se a pilha contiver elementos • imprimir a pilha

(3)

2.1. Primeira definição de Pilha Estática

Trabalha-se com a idéia de ter um vetor de inteiros e o topo é controlado por uma variável inteira fora desse vetor.

#define MAX 100

typedef int def_pilha[MAX];

A referência é feita da seguinte forma para:

def_pilha pilha; int topo;

Topo => topo

Elemento do topo => pilha[topo]

As Rotinas:

1. Verificação se a pilha contém ou não elementos

boolean vazia (int topo){ return (topo == -1); }

2. Verificação se a pilha já está cheia, ou seja, se não comporta mais elementos

boolean cheia (int topo){

return (topo == (MAX-1)); }

3. Empilhar um elemento, ou seja, inserir um elemento no topo da pilha

boolean empilha (def_pilha pilha, int *topo, int x){ if (cheia(*topo))return False;

pilha[++(*topo)]=x; return True;

}

4. Desempilhar elemento, ou seja, retirar um elemento do topo da pilha

boolean desempilha (def_pilha pilha, int *topo, int x){ if (vazia(*topo))return False;

*x = pilha[(*topo)--];

return True; }

(4)

Exemplo 01:

Implementar uma rotina para conversão de um número inteiro em decimal para um número binário.

void converter_nro(int elemento, def_pilha binario, int* topo){ int resto;

inicializa_pilha(binário,topo); while (elemento != 0) {

resto = elemento % 2;

empilha(binario, topo, resto); elemento = elemento / 2;} }

2.2. Segunda definição de Pilha estática

Essa definição trabalha com uma estrutura que contem um vetor de elementos e uma variável inteira para guardar a posição do topo. Todas as operações são executadas em cima dessa estrutura.

#define MAX 10 typedef struct {

int topo;

int elementos[MAX];

} def_pilha;

A referência é feita da seguinte forma para:

def_pilha pilha;

Topo => pilha.topo

Elemento do topo => pilha.elementos[pilha.topo]

As Rotinas:

1. Verificação se a pilha tem elementos

boolean vazia (def_pilha pilha){ return (pilha.topo == -1); }

2. Verificação se a pilha já está cheia, ou seja, se não comporta mais elementos

boolean cheia (def_pilha pilha){ return (pilha.topo == (MAX-1)); }

(5)

3. Empilhar um elemento, ou seja, inserir um elemento no topo da pilha

boolean empilha (def_pilha *pilha, int x){ if (cheia(*pilha)) return False;

pilha->elementos [++(pilha->topo)] = x; return True;

}

4. Desempilhar elemento, ou seja, retirar um elemento do topo da pilha

boolean desempilha (def_pilha *pilha, int *x){ if (vazia(*pilha)) return False;

*x = pilha->elementos[pilha->topo--];

return True;

}

5. Imprimir a pilha sem retirar elementos

void mostra_pilha (def_pilha pilha){

int i=pilha.topo;

if (pilha.topo >= 0){ for(; i>=0; i--)

printf("\t%d",pilha.elementos[i]);} else printf(" esta vazia");

}

Exemplo 02:

Escrever uma rotina para inverter uma frase usando pilha.

void converter_frase(char frase[MAX], def_pilha* pilha){

int i=0;

for (;i<strlen(frase);i++) empilha(pilha,frase[i]); }

3. Pilhas usando Lista Linear Simplesmente Encadeada

Definição:

Typedef struct no_pilha{

int info;

struct no_pilha *prox;

} *def_pilha;

(6)

As Rotinas:

1. Inicialização de uma pilha

void inicializa (def_pilha *pilha){ *pilha = NULL;

}

2. Verificação se a pilha tem elementos

boolean vazia(def_pilha pilha){

return(pilha==NULL);

}

3. Empilhar um elemento, ou seja, inserir um elemento no topo da pilha

void empilha(int numero, def_pilha *pilha){ def_pilha q = cria_no(numero);

if (!vazia(*pilha)) q->prox = *pilha; *pilha = q;

}

4. Desempilhar elemento, ou seja, retirar um elemento do topo da pilha

boolean desempilha(int *numero,def_pilha * pilha){ def_pilha q;

if(vazia(*pilha)) return False; q = (*pilha); *numero = q->info; *pilha = (*pilha)->prox; free(q); return True; }

6. Imprimir a pilha sem retirar elementos

void imprime(def_pilha pilha){ while (pilha!=NULL){

printf("\t%d", pilha->info); pilha=pilha->prox;};

printf("\n"); }

(7)

4. Pilhas usando Lista Linear Simplesmente Encadeada com

Descritor

typedef struct no_pilha{ int info;

struct no_pilha *prox;

} No;

typedef struct descritor{

int quantidade;

No *pilha;

} *def_pilha;

Da mesma forma, a inserção e remoção serão feitas no início da mesma.

As Rotinas:

1. Inicialização de uma pilha

void inicializa (def_pilha *Pilha) {

Pilha->quantidade=0; Pilha->pilha = NULL; }

2. Verificação se a pilha tem elementos

boolean vazia(def_pilha pilha) {

return(pilha.pilha==NULL);

}

3. Empilhar um elemento, ou seja, inserir um elemento no topo da pilha

void empilha(int numero, def_pilha *pilha) { No* q = cria_no(numero);

if (!vazia(*pilha)) q->prox = (*pilha).pilha; (*pilha).pilha = q;

(*pilha).quantidade++; }

4. Desempilhar elemento, ou seja, retirar um elemento do topo da pilha

boolean desempilha(int *numero, def_pilha *Pilha) { No* q;

if(vazia(*Pilha)) return False; q = Pilha->pilha; *numero = q->info; Pilha->pilha = Pilha->pilha->prox; free(q); Pilha->quantidade--; return True; }

6. Imprimir a pilha sem retirar elementos

void imprime(def_pilha pilha) { while (pilha.pilha!=NULL){

printf("\t%d", pilha.pilha->info); pilha=pilha->prox;};

printf("\n"); }

(8)

Exemplo 03:

O estacionamento Bashemin contém uma única alameda que guarda carros. Existe apenas uma entrada/saída no estacionamento, em uma extremidade da alameda. Se chegar um cliente para retirar um carro que não seja o mais próximo da saída, todos os carros bloqueando seu caminho sairão do estacionamento, e os outros carros voltarão a ocupar a seqüência inicial. Escreva um programa que processe um grupo de linhas de entrada.

O programa deve imprimir uma mensagem sempre que um carro sair.

Quando um carro sair do estacionamento, a mensagem deverá incluir o número de vezes em que o carro foi manobrado para fora do estacionamento para permitir que outros carros saíssem.

#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <string.h>

typedef enum {False,True} boolean; struct carros{

char placa[7];

int manobra;}; typedef struct no_pilha{

struct carros info;

struct no_pilha *prox;

} No; typedef struct descritor{

int quantidade;

No *pilha;

} def_pilha;

void inicializa(def_pilha *Pilha) {

Pilha->quantidade=0; Pilha->pilha=NULL; }

boolean vazia(def_pilha Pilha) {

return(Pilha.pilha==NULL);

}

No* cria_no(struct carros dados) { No* q;

q =(No*) malloc(sizeof(struct no_pilha)); q->info=dados;

q->prox=NULL; return q; }

void empilha(struct carros dados, def_pilha* Pilha)

{ No* q=cria_no(dados);

if(!vazia(*Pilha))q->prox = Pilha->pilha; Pilha->pilha = q;

Pilha->quantidade++; }

(9)

boolean desempilha(struct carros *dados, def_pilha* Pilha) { No* q;

if (vazia(*Pilha)) return False; q = Pilha->pilha; *dados = q->info; Pilha->pilha = Pilha->pilha->prox; free(q); Pilha->quantidade--; return True; }

void imprime(def_pilha pilha)

{ printf("\n\nOs carros no estacionamento: \n"); while (pilha.pilha!=NULL){ printf("%s - ",(pilha.pilha->info).placa); printf("%d\n", (pilha.pilha->info).manobra); pilha.pilha = pilha.pilha->prox;}; printf("\n"); }

boolean retira(def_pilha* pilha, struct carros* dados) { def_pilha q,p;

booelean achou = False;; struct carros carro;

q = *pilha; inicializa(&p); while (!vazia(q) && !achou){

desempilha(&carro,&q);

if (strcmp(carro.placa,dados->placa) != 0) empilha(carro,&p);

else{ achou = True;

dados->manobra = carro.manobra;}} while (desempilha(&carro,&p)){ (carro.manobra)++; empilha(carro,&q); } (*pilha) = q; return achou; }

int main (void)

{ def_pilha estacionamento; struct carros carro; int opcao; inicializa(&estacionamento); do{ do{ printf("\n(1)Entrada\n(2)Saida\n(3)Imprimir\n(4)Encerrar\nOpcao="); opcao=getche()-48;

}while (opcao<0 && opcao>4); switch(opcao){

case 1: printf("\n\nQual a placa do carro = ");

scanf("%s",&carro.placa);

carro.manobra = 0;

empilha(carro,&estacionamento);break;

case 2: if (vazia(estacionamento))

printf("\nNao tem mais carros ...\n");

else{

printf("\nQual a placa do carro = "); scanf("%s",&carro.placa);

if (retira(&estacionamento,&carro))

(10)

vezes\n",carro.placa,carro.manobra);

else printf("O carro de placa %s nao se encontra mais aqui \n",carro.placa);}

break;

case 3: if (!vazia(estacionamento)) imprime(estacionamento);

else printf("Nao tem mais carros ...\n");printf("\n\n");

break;} }while (opcao != 4);

printf("\n\n\aDigite algo para encerrar....");getch(); return 1;

}

5. Exercícios:

1) (Pilha Estática) Construir uma pilha que usa somente um vetor, onde pilha[0] contém o controle do topo da pilha e pilha[1] a pilha[MAX-1] contêm os elementos da pilha. Defina as rotinas de: a) inicialização da pilha

b) verificação de pilha vazia c) verificação de pilha cheia d) empilhar um elemento e) desempilhar um elemento f) mostrar a pilha

2) (Pilha Estática) Em algumas aplicações tem-se que trabalhar com mais de uma pilha ao mesmo tempo. Pode-se implementar essas pilhas num mesmo vetor, de forma que cada uma ocupe parte desse vetor. Faça um programa que tenha duas pilhas alocadas em um mesmo vetor, onde cada uma cresce em sentido oposto, sem que as duas fiquem totalmente ocupadas simultaneamente. Implemente as operações básicas de

a) inicialização das duas pilhas

b) verificação se as pilhas estão vazias c) verificação se as pilhas estão cheias

d) empilhar um elemento em cada uma das pilhas e) desempilhar um elemento de cada uma das pilhas f) mostrar as pilhas

3) (Pilha Estática) Um estacionamento é composto de um único beco que guarda no máximo 10 carros. Existe apenas uma entrada/saída no estacionamento, em uma extremidade do beco. Se chegar um cliente para retirar um carro que não seja o mais próximo da saída, todos os carros bloqueando seu caminho sairão do estacionamento, e os outros carros voltarão a ocupar a seqüência inicial. Escreva um programa que processe um grupo de cartões do estacionamento. O programa deve imprimir uma mensagem sempre que um carro chegar ou sair. Quando um carro chegar, a mensagem deve especificar se existe ou não vaga para o carro no estacionamento. Se não houver vaga, o carro partirá sem entrar no estacionamento.

Quando um carro sair do estacionamento, a mensagem deverá incluir o número de vezes em que o carro foi manobrado para fora e para dentro do estacionamento para permitir que outros carros saíssem.

4) (Pilha Dinâmica) Imagine um colecionador de vinhos que compra vinhos recentes e guarda-os em uma adega para envelhecerem, e que a cada ocasião especial abre sempre sua última aquisição (para poupar os mais antigos). Construa um programa que:

(11)

b) Informe qual vinho deve ser aberto em uma ocasião especial c) Relacione as cinco aquisições mais antigas

As informações básicas que o registro do vinho deve conter são: nome do produto e safra.

5) (Pilha Dinâmica) O problema das Torres de Hanói é bastante estudado em computação. O problema consiste em n discos de diferentes diâmetros e três estacas: A, B e C. Inicialmente os discos estão encaixados na estaca A onde o menor está sempre encima do maior disco. O objetivo é deslocar os discos para uma estaca C, usando a estaca B como auxiliar. Somente o primeiro disco de toda estaca pode ser deslocado. Isso para nós dá a idéia de pilhas. Portanto construa a resolução desse exercício usando pilhas e para n = 4, ou seja, para 04 discos.

6) (Pilha Dinâmica) Uma pilha pode ser usada para rastrear os tipos de escopos encontrados numa expressão matemática e verificar se o uso deles está correto. Os delimitadores de escopos podem ser os parênteses, os colchetes e as chaves. Escreva um programa que leia uma expressão matemática e verifique se os escopos estão posicionados de forma correta.

7) (Pilha Dinâmica) Considere a existência de um tipo PILHA de números de ponto flutuante. Implemente um programa que leia duas pilhas, P1 e P2, e passe todos os elementos da pilha P2 para o topo da pilha P1 sem trocar a ordem e sem ferir o conceito de pilha. A figura a seguir ilustra essa concatenação de pilhas:

8) (Pilha Dinâmica) Considere que a pilha use a estrutura de uma Lista Circular Simplesmente Encadeada. Implemente as operações básicas de:

a) inicialização da pilha

b) verificação se a pilhas está vazia c) empilhar um elemento na pilha d) desempilhar um elemento da pilha e) mostrar a pilha

9) (Pilha Dinâmica) Considere que a pilha use a estrutura de uma Lista Linear Simplesmente Encadeada com Descritor Dinâmico. Implemente as operações básicas de:

a) inicialização da pilha

b) verificação se a pilhas está vazia c) empilhar um elemento na pilha d) desempilhar um elemento da pilha e) mostrar a pilha

Referências

Documentos relacionados

Disto pode-se observar que a autogestão se fragiliza ainda mais na dimensão do departamento e da oferta das atividades fins da universidade, uma vez que estas encontram-se

A partir de pesquisa documental são apresentadas as premissas adotadas para a projeção das demandas sazonais, o estudo de disponibilidade hídrica para períodos hidrológicos

Local para estágio CNPJ Valido até Localidade.. 1 Acácia Comércio de

Este estudo evidencia o quanto a situação epidemiológica da Covid-19 e as medidas necessárias para o seu con- trole influenciaram sobre a situação dos estoques e disponibilidade

A figura 4.31 ilustra este cenário, onde é possível notar que para um sistema multicelular, mesmo quando são utilizados có- digos com entrelaçadores maiores, o algoritmo não

” Essa singularidade das trajetórias individuais reafirma, para Souza (2004, p. 196), a ideia da “especificidade de cada percurso de vida”. São as narrativas de formação,

RESUMO: 1- Não  é  para  ficarmos  ignorantes em relação aos dons.. 2- Os  dons  podem

(1996), em seu estudo sobre produção de aglomerados com mistura de Pinus elliottii e Eucalyptus dunnii, demonstrou que com o aumento na razão de compactação, devido à maior