• Nenhum resultado encontrado

aula6 pilha fila

N/A
N/A
Protected

Academic year: 2021

Share "aula6 pilha fila"

Copied!
41
0
0

Texto

(1)

Estrutura de Dados

Universidade Federal de Juiz de Fora Departamento de Ciˆencia da Computac¸˜ao

(2)

I Introduc¸˜ao I Pilha

I Implementac¸˜ao com vetor

I Implementac¸˜ao encadeada

I Fila

I Implementac¸˜ao com vetor

I Implementac¸˜ao encadeada

I Exerc´ıcios

(3)

I Pilhas e Filas s˜ao estruturas de dados utilizadas em v´arias aplicac¸ ˜oes.

I Pilhas e Filas s˜ao listas que possuem uma disciplina de acessobem definida.

I Exemplos:

I Pilha de pratos

I Fila de banco

(4)

I A pilha ´e uma lista onde todas as inclus ˜oes e exclus ˜oes de n ´os s˜ao feitas em uma ´unica extremidade.

I Essa extremidade ´e conhecida como topo.

I Usa-se o crit´erio de retirar em primeiro lugar o ´ultimo n ´o que foi inclu´ıdo na lista.

I Este crit´erio ´e conhecido como FILO (First In Last Out). I A ideia desta estrutura ´e a de uma pilha de pratos.

(5)
(6)

Representac¸˜ao com vetor

I Representac¸˜ao com vetor (ou contiguidade dos n ´os). I Esquematicamente, uma pilha cont´ıgua com capacidade

m´axima para n n ´os pode ser representada da seguinte forma:

vet

topo

0 1 2 3 4 5 6 ... n-2 n-1 3 30 13 58 57 6 / 41

(7)

I Desta forma, o TAD PilhaCont para representar uma pilha de n ´umeros inteiros, pode ser implementado como:

class PilhaCont

{

private:

int max; // capacidade maxima

int topo; // posicao do topo da pilha

int *vet; // vetor que armazena os dados da pilha

public:

PilhaCont(int tam);

∼PilhaCont();

int getTopo(); // valor do No no Topo

void empilha(int val);// insere No no Topo

int desempilha(); // elimina No do Topo

bool vazia();

};

(8)

Representac¸˜ao com vetor

PilhaCont::PilhaCont(int tam)

{

max = tam;

topo = -1;

vet = new int[max];

}

PilhaCont::∼PilhaCont()

{

delete [] vet;

}

I O construtor cria inicialmente uma pilha vazia. I A pilha vazia ´e marcada com topo com o valor −1. I Condic¸˜ao de pilha vazia: topo == -1.

(9)

int PilhaCont::getTopo() { if(topo != -1) return vet[topo]; else {

cout << "ERRO: Pilha vazia!" << endl; exit(1); } } bool PilhaCont::vazia() { return (topo == -1); } 9 / 41

(10)

Representac¸˜ao com vetor

void PilhaCont::empilha(int val)

{

if(topo == (max - 1)){

cout << "ERRO: Vetor Cheio!" << endl; exit(2); } topo = topo + 1; vet[topo] = val; } int PilhaCont::desempilha() { if(topo == -1){

cout << "ERRO: Pilha vazia!" << endl; exit(1); } topo = topo - 1; return vet[topo + 1]; } 10 / 41

(11)

I Uma pilha de valores inteiros com n n ´os pode ser representadaatrav´es de uma lista simplesmente encadeada. topo 25 1 -9 45

I Portanto, ser´a necess´ario definir dois TADs: No e PilhaEncad.

(12)

Representac¸˜ao encadeada

I O TAD No possui a mesma implementac¸˜ao usada anteriormente para uma lista simplesmente encadeada.

class No

{

public:

// ...

private:

int info; // informacao do No

No *prox; };

(13)

class PilhaEncad { public: PilhaEncad(); ∼PilhaEncad(); int getTopo();

void empilha(int val);

int desempilha(); bool vazia(); private: No * topo; }; 13 / 41

(14)

Representac¸˜ao encadeada PilhaEncad::PilhaEncad() { topo = NULL; } PilhaEncad::∼PilhaEncad() { No *p = topo;

while(topo != NULL)

{ topo = p->getProx(); delete p; p = topo; } } 14 / 41

(15)

int PilhaEncad::getTopo() { if(topo != NULL) return topo->getInfo(); else {

cout << "ERRO: Pilha vazia!" << endl; exit(1);

} }

void PilhaEncad::empilha(int val)

{ No *p = new No(); p->setInfo(val); p->setProx(topo); topo = p; } 15 / 41

(16)

int PilhaEncad::desempilha() { No *p; int val; if(topo != NULL) { p = topo; topo = p->getProx(); val = p->getInfo(); delete p; } else exit(1); return val; } bool PilhaEncad::vazia() {

return (topo == NULL)

}

(17)

I Assim como as pilhas, as filas tamb´em possuem uma disciplina de acesso bem definida:

I A fila ´e uma lista onde todas as inclus ˜oes s˜ao feitas em

uma extremidadee todas as exclus ˜oes na outra

extremidade.

I Usa-se o crit´erio de retirar em primeiro lugar o primeiro n ´o

inclu´ıdo na lista.

I Este crit´erio ´e chamado de FIFO (First In First Out).

I Esta estrutura ´e equivalente a uma fila de banco.

(18)

FIM xn xn-1xn-2 x3 x2 x1 INÍCIO DESENFILEIRA ENFILEIRA I Representac¸ ˜oes: I Cont´ıgua I Encadeada 18 / 41

(19)

I Representac¸˜ao por contiguidade dos n ´os.

I Uma fila cont´ıgua onde j´a ocorreram (n + 1) entradas e k sa´ıdas de n ´os, teria a seguinte representac¸˜ao esquem´atica:

vet

inicio

0 1 2 3 4 5 6 7 8 9 30 13 58 57

fim

5

max

3 8 10

I Sendo inicio o ´ındice do vetor que cont´em o n ´o do comec¸o e fim o ´ındice do n ´o que est´a no final.

(20)

class FilaCont {

private:

int max; // maximo de elementos do vetor

int inicio;// indice do No que esta no inicio

int fim; // indice da posicao apos o ultimo No

int *vet; // vetor que armazena a fila

public:

FilaCont(int tam);

∼FilaCont();

int getInicio(); // valor do No no inicio

void enfileira(int val);// insere No no fim

int desenfileira(); // elimina No do inicio

bool vazia(); // verifica se esta vazia

};

(21)

I Construtor e destrutor

FilaCont::FilaCont(int tam)

{

max = tam; inicio = 0; fim = 0;

vet = new int[max];

} FilaCont::∼FilaCont() { delete [] vet; } 21 / 41

(22)

int FilaCont::getInicio() {

if (!vazia())

return vet[inicio];

else {

cout << "ERRO: Fila vazia" << endl; exit(1);

} }

void FilaCont::enfileira(int val)

{

if(fim == max) // fila cheia

{

cout << "ERRO: Fila cheia" << endl; exit(2); } vet[fim] = val; fim = fim + 1; } 22 / 41

(23)

int FilaCont::desenfileira() { if(!vazia()) { inicio = inicio + 1; return vet[inicio - 1]; }

cout << "ERRO: Fila vazia" << endl; exit(1); } bool FilaCont::vazia() { return (inicio==fim); } 23 / 41

(24)

I O TAD FilaCont apresentaalgumas restric¸ ˜oes.

vet

2 3 3 4 5 6

inicio fim 0 1 2 3 4 5 6 7 8 9 10 11 12 índices inicio = 6 fim = 12 max = 12 Situação da Fila

I Quando fim = max n˜ao se pode mais inserir na fila. I Por´em, se inicio > 0 ent˜ao existe espac¸o no in´ıcio da fila. I Esse espac¸o deveria ser usado para inserir mais n ´os na fila. I A soluc¸˜ao mais comum ´e utilizar uma representac¸˜ao

circular do vetor que representa a fila.

(25)

I Ideia: todos os incrementos em inicio e fim, quando sai e entra n ´o na fila, devem ser realizados m ´odulo max. I TAD Fila Circular:

... ... 0 1 2 i i+1 i+2 max-1 max-2 Situação da Fila inicio = i fim = 2 3 Nó Nó Nó Nó Nó Nó Nó i-1 inicio fim 25 / 41

(26)

I Exemplo:

vet

inicio

0 1 2 3 4 5 6 7 8 9 30 13 58 57

fim

5

max

3 1 10 -33 22 -88

I E se mais dois valores fossem inseridos na fila?

I Nesse caso, inicio=fim e assim a condic¸˜ao de fila vazia se confundiria com a de fila cheia.

I Para evitar esse problema usa-se um contador n para saber quantos valores est˜ao de fato na fila.

(27)

class FilaCirc {

private:

int max; // maximo de elementos do vetor

int inicio; // indice do No que esta no inicio

int fim; // indice do No que esta no fim

int n; // numero atual de elementos do vetor

int *vet; // vetor que armazena a fila

int inc(int ind); // incrementa indice

public:

FilaCirc(int tam);

∼FilaCirc();

int getInicio(); // consulta No do inicio

void enfileira(int val); // insere No no fim

int desenfileira(); // elimina No do inicio

bool vazia(); // verifica se esta vazia

};

(28)

Incremento circular

I A operac¸˜ao de incremento circular para o TAD Fila Circular pode ser implementada da seguinte forma:

int FilaCirc::inc(int ind)

{ if (ind == max-1) return 0; else return ind+1; } // ou

int FilaCirc::inc(int ind)

{

return (ind+1) % max;

}

(29)

I Construtor: precisa ser modificado para incluir n, o n ´umero de n ´os presentes na fila.

FilaCirc::FilaCirc(int tam)

{

max = tam; // capacidade maxima

n = 0; // numero de nos na fila

inicio = fim = 0; // inicio, fim

vet = new int[max]; // vetor com os dados

} FilaCirc::∼FilaCirc() { delete [] vet; } 29 / 41

(30)

I Operac¸˜ao getInicio(): sem alterac¸ ˜oes com relac¸˜ao ao TAD anterior FilaCont.

I A condic¸˜ao de fila vazia agora ´e diferente.

I ´E preciso verificar o valor de n, que representa o n ´umero de n ´os inseridos na fila:

I se n = 0: a fila est´a vazia;

I se n = max: a fila est´a cheia, n˜ao ´e poss´ıvel inserir mais n ´os.

bool FilaCirc::vazia()

{

return (n==0);

}

I Para o TAD FilaCirc s ´o ´e preciso mudar as operac¸ ˜oes de entrada e sa´ıda da fila usando o incremento circular .

(31)

void FilaCirc::enfileira(int val) {

if(n == max) {

cout << "ERRO: Fila cheia" << endl; exit(1); } vet[fim] = val; fim = inc(fim); n = n + 1; } 31 / 41

(32)

int FilaCirc::desenfileira() {

if(!vazia())

{

int val = vet[inicio];

inicio = inc(inicio); n = n - 1;

return val;

}

cout << "ERRO: Fila vazia" << endl; exit(1);

}

(33)

I Representac¸˜ao por encadeamento dos n ´os.

I Esquematicamente, seja uma fila encadeada com n n ´os: inicio fim

I Para representar uma fila dessa forma, ´e preciso definir dois TADs:

I No

I FilaEncad

(34)

I Definic¸˜ao da classe do TAD No (No.h)

I Pode-se utilizar o mesmo n ´o definido anteriormente para uma lista simplesmente encadeada ou pilha encadeada.

class No

{

public:

// ...

private:

int info; // informacao do No

No *prox; };

(35)

I Definic¸˜ao da classe do TAD FilaEncad I Arquivo: FilaEncad.h

class FilaEncad

{

private:

No *inicio; // ponteiro para No do comeco

No *fim; // ponteiro para No do fim

public:

FilaEncad(); ∼FilaEncad();

int getInicio(); // retorna No do inicio

void enfileira(int val); // insere No no fim

int desenfileira(); // elimina No do inicio

bool vazia(); // verifica se esta vazia

};

(36)

I Arquivo: FilaEncad.cpp FilaEncad::FilaEncad() { inicio = NULL; fim = NULL; } FilaEncad ::∼FilaEncad () { No *p = inicio;

while(inicio != NULL)

{ inicio = p->getProx(); delete p; p = inicio; } } 36 / 41

(37)

bool FilaEncad::vazia() {

// verifica se fila esta vazia

if(inicio == NULL) return true; else return false; } int FilaEncad::getInicio() { if(inicio != NULL) return inicio->getInfo(); else {

cout << "ERRO: Fila vazia!" << endl; exit(1);

} }

(38)

void FilaEncad::enfileira(int val) { No *p = new No(); p->setInfo(val); p->setProx(NULL); if(fim == NULL)

inicio = p; // insere o primeiro No

else

fim->setProx(p); // liga No p na fila

fim = p; // No p passa a ser o ultimo

}

(39)

int FilaEncad::desenfileira() { No *p; if(inicio != NULL) { p = inicio; inicio = p->getProx(); if(inicio == NULL)

fim = NULL; // a fila esvaziou

int val = p->getInfo();

delete p; // exclui o No do inicio

return val;

}

cout << "ERRO: Fila vazia" << endl; exit(1);

(40)

1. Desenvolver uma func¸˜ao para inverter o sentido de uma filarepresentada por uma lista encadeada.

2. Considerando uma pilha representada por uma lista encadeada onde cada n ´o possui um valor inteiro,

desenvolver um procedimento para desempilhar os seus n ´os montando uma lista circular (duplamente encadeada). 3. O gerente de desenvolvimento de aplicac¸ ˜oes de uma

empresa observou que diversos programas trabalham com filasencadeadas que devem ser gravadas em mem ´oria auxiliar. Para isso ´e necess´ario representar a fila

contiguamente. Desenvolver um procedimento para fazer esta transformac¸˜ao sabendo que cada n ´o possui um valor inteiro e que uma fila possui no m´aximo 500 n ´os.

(41)

inversa da anterior, i.e., de fila cont´ıgua para fila encadeada.

5. Desenvolver um procedimento para montar duas filas cont´ıguas, sendo que uma deve conter somente n ´umeros inteiros negativos, e a outra os demais n ´umeros. Os n ´umeros inteiros ser˜ao fornecidos atrav´es de uma pilha encadeada em que cada n ´o possui um n ´umero inteiro e qualquer. Considerar que a pilha possui no m´ax. 100 n ´os. 6. Desenvolver um programa para ler diversos valores

inteiros e montar uma fila encadeada, usando o TAD FilaEncad e atendendo as seguintes caracter´ısticas:

a) O ´ultimo valor a ser lido ´e um FLAG com X = 0.

b) Na fila s ´o podem entrar n ´os com X > 0 e maior que a

informac¸˜ao X do ´ultimo n ´o j´a inclu´ıdo na fila.

c) Para cada valor X < 0 lido, retirar um n ´o da fila, se n˜ao for vazia.

Referências

Documentos relacionados

A) Criar um cadastro municipal de alunos com altas habilidades ou superdotação matriculados somente na educação básica, a fim de fomentar a execução de políticas

17 CORTE IDH. Caso Castañeda Gutman vs.. restrição ao lançamento de uma candidatura a cargo político pode demandar o enfrentamento de temas de ordem histórica, social e política

Dessa forma, os documentos foram analisados quanto aos tipos de projetos residenciais que se aplicam (Triagem); quais são os conteúdos mínimos indicados para

O presente trabalho, considerando as literaturas consultadas, visou verificar os processos de alteração da molhabilidade da rocha e da adsorção dos tensoativos,

A inscrição do imóvel rural após este prazo implica na perda do direito de manter atividades agropecuárias em áreas rurais consolidadas em APP e Reserva Legal, obrigando

Junto com a eliminação de glicose, envolve diretamente a perda de eletrólitos e água ocorrendo poliuria, polidipsia, desidratação e hemoconcentração..

O sistema de avaliação será aplicado conforme o RAPM e/ou RCFAPM e o previsto neste Plano de Curso, sendo o corpo docente responsável pela elaboração das

Após aplicação repetida de 2-10 g de EMLA nas úlceras da perna com uma área até 62 cm 2 , por períodos de 30-60 minutos, 3-7 vezes por semana, num máximo de 15 doses, durante