Buscar

05.ED.Pilhas e Filas-2014-1

Prévia do material em texto

DCC013 
 
Estruturas de Dados 
Pilhas e Filas 
 
Definição 
 São listas que possuem uma disciplina de 
acesso: 
 Pilha é uma lista onde todas as inclusões e 
exclusões de nós são feitas em uma única 
extremidade. 
 Usa-se o critério de retirar em primeiro lugar o 
último nó que foi incluído na lista. 
 Este critério é conhecido como FILO (First In Last 
Out). 
 A ideia desta estrutura é a de uma pilha de pratos. 
Pilhas e Filas 
2 
Definição 
 Visão genérica da estrutura de dados pilha: 
Pilhas e Filas 
3 
FUNDO 
EMPILHA DESEMPILHA 
TOPO 
X1 
X2 
X3 
Xn - 1 
Xn 
Definição 
Fila é uma lista onde todas as inclusões são 
feitas em uma extremidade e todas as exclusões 
na outra extremidade. 
Usa-se o critério de retirar em primeiro lugar o 
primeiro nó incluído na lista. 
Este critério é chamado de FIFO (First In First 
Out). 
Esta estrutura é equivalente a uma fila de banco. 
Pilhas e Filas 
4 
Definição 
 Visão genérica da estrutura de dados fila: 
Pilhas e Filas 
5 
X1 X2 X3 X Xn ENTRA 
FIM INÍCIO 
SAI 
n-1 
X 
n-2 
Representação por contiguidade dos nós 
 Esquematicamente, seja uma pilha contígua de n 
nós: 
Pilhas 
6 
 
0 1 2 . . . n-1 n . . . m-1 
 
 X = NO0 NO1 NO2 . . . NOn-1 - . . . - 
 
 topo 
 n - 1 
 
 Desta forma, o TAD TPilhaCont de elementos 
reais poderia ser: 
TAD TPilhaCont 
Pilhas 
7 
class TPilhaCont 
{ 
 private: 
 int m; // capacidade máxima de elementos do vetor 
 int topo;// índice do No que está no topo da pilha 
 float *X; // vetor que armazena a pilha 
 public: 
 TPilhaCont(int tam); 
 float ConsultaTopoPC(); 
 void EmpilhaPC(float val); // insere No no Topo
 
 void DesempilhaPC(); // elimina No do Topo 
 bool VaziaPC(); // verifica se pilha está vazia 
 ~TPilhaCont(); 
}; 
 
0 1 2 . . . n-1 n . . . m-1 
 
 X = NO0 NO1 NO2 . . . NOn-1 - . . . - 
 
 topo 
 n - 1 
 
 Construtor e destrutor: 
Pilhas 
8 
TPilhaCont::TPilhaCont(int tam) 
{ 
 m = tam; 
 topo = -1; 
 X = new float[m]; 
} 
TPilhaCont::~TPilhaCont() 
{ 
 delete [] X; 
} 
MI do TAD TPilhaCont 
Condição de pilha contígua vazia: 
topo = -1 
Pilhas 
9 
float TPilhaCont::ConsultaTopoPC() 
{ 
 if(topo != -1) 
 return X[topo]; 
 else 
 { 
 cout << “Pilha vazia!” << endl; 
 exit(1); 
 } 
} 
 Operação ConsultaTopoPC: 
MI do TAD TPilhaCont 
Pilhas 
10 
void TPilhaCont::EmpilhaPC(float val); 
{// insere No contendo val no topo da Pilha
 
 if(topo == (m – 1)) 
 { 
 cout << “Vetor Cheio!” << endl; 
 exit(2); 
 } 
 topo = topo + 1; 
 X[topo] = val; 
} 
 Operação EmpilhaPC: 
MI do TAD TPilhaCont 
Pilhas 
11 
void TPilhaCont::DesempilhaPC() 
{ // elimina No do topo da pilha
 
 if(topo == -1) 
 { 
 cout << “Pilha Vazia!” << endl; 
 exit(3); 
 } 
 topo = topo - 1; 
} 
 Operação DesempilhaPC: 
MI do TAD TPilhaCont 
Pilhas 
12 
bool TPilhaCont::VaziaPC() 
{ // verifica se pilha está vazia
 
 if(topo == -1) 
 return(true); 
 else 
 return(false); 
} 
 Operação VaziaPC: 
MI do TAD TPilhaCont 
Representação por encadeamento dos nós 
 Uma pilha com n nós pode ser representada por 
uma lista simplesmente encadeada. 
Esquematicamente: 
Pilhas 
13 
 Assim, é necessário definir dois TAD’s: No e 
TPilhaEncad. 
 Xn Xn – 1 X2 X1 
topo 
Pilhas 
14 
class No 
{ 
 private: 
 float info; // informação real do No 
 No *prox; // ponteiro para o próximo No 
 public: 
 No(); 
 void atribInfo(float val); 
 void atribProx(No *p); 
 float consultaInfo(); 
 No *consultaProx(); 
 ~No(); 
}; 
Representação por encadeamento dos nós 
 TAD No (Definição  No.h): 
Pilhas 
15 
No::No() {} 
 
void No::atribInfo(float val) { info = val; } 
 
void No::atribProx(No *p) { prox = p; } 
 
float No::consultaInfo() { return info; } 
 
No *No::consultaProx() { return prox; } 
 
No::~No() {} 
Representação por encadeamento dos nós 
 MI do TAD No (Definição  No.h): 
Pilhas 
16 
class TPilhaEncad 
{ 
 private: 
 No *topo; // ponteiro para o No do topo da pilha 
 public: 
 TPilhaEncad(); 
 float ConsultaTopoPE(); 
 void EmpilhaPE(float val); // insere No no Topo
 
 void DesempilhaPE(); // elimina No do Topo 
 bool VaziaPE(); // verifica se pilha está vazia 
 ~TPilhaEncad(); 
}; 
TAD TPilhaEncad 
 Xn Xn – 1 X2 X1 
topo 
 Construtor: 
Pilhas 
17 
TPilhaEncad::TPilhaEncad() 
{ 
 topo = NULL; 
} 
MI do TAD TPilhaEncad 
Condição de pilha encadeada vazia: 
topo = NULL 
Pilhas 
18 
 Operação ConsultaTopoPE: 
float TPilhaEncad::ConsultaTopoPE() 
{ 
 if(topo != NULL) 
 return topo->consultaInfo(); 
 else 
 { 
 cout << “Pilha vazia!” << endl; 
 exit(1); 
 } 
} 
MI do TAD TPilhaEncad 
Pilhas 
19 
 Operação EmpilhaPE: 
void TPilhaEncad::EmpilhaPE(float val)
 
{ // insere No contendo val no topo da pilha 
 No *p = new No(); // aloca No apontado por p 
 p->atribInfo(val); // preenche info com val 
 p->atribProx(topo); // prox recebe atual topo 
 topo = p; //No apontado por p passa a ser o topo 
} 
MI do TAD TPilhaEncad 
Pilhas 
20 
 Operação DesempilhaPE: 
void TPilhaEncad::DesempilhaPE() 
{ // elimina No do topo da pilha
 
 No *p; 
 if(topo != NULL) // se pilha não está vazia 
 { 
 p = topo; // p aponta para o No a ser excluído 
 topo = p->consultaProx();//topo passa a apontar 
 // para o atual segundo 
 delete p; // exclui o No do topo 
 } 
 else 
 Rotina_Erro(1); 
} 
MI do TAD TPilhaEncad 
Pilhas 
21 
bool TPilhaEncad::VaziaPE() 
{ // verifica se pilha está vazia 
 
 if(topo == NULL) 
 return(true); 
 else 
 return(false); 
} 
 Operação VaziaPE: 
MI do TAD TPilhaEncad 
Pilhas 
22 
 Destrutor: 
TPilhaEncad::~TPilhaEncad() 
{ 
 No *p = topo; 
 while(topo != NULL) 
 { 
 topo = p->consultaProx(); 
 delete p; 
 p = topo; 
 } 
} 
MI do TAD TPilhaEncad 
 Exercício 1: 
 Existem PA’s que utilizam estruturas de dados 
dinâmicas, cujos projetos preveem uma possível 
interrupção no processamento com retomada num 
momento futuro. 
 Uma alternativa para esses programas pode ser a 
transformação da estrutura encadeada em contígua, 
viabilizando o seu armazenamento em memória 
auxiliar e, quando necessário, a recuperação da 
estrutura contígua e posterior transformação 
inversa (em encadeada) para prosseguir com o 
processamento do PA. 
Pilhas 
23 
 Exercício 1: 
 Para auxiliar nesta tarefa, desenvolver um 
procedimento para o PA que transforme uma pilha 
encadeada de valores reais em pilha contígua com 
no máximo 500 nós. 
Pilhas 
24 
void PEncadPCont(PilhaEncad *pe, PilhaCont *pc) 
{ 
 pc = new PilhaCont(500);//cria pilha contígua 
 while(!pe->VaziaPE())//enquanto encadeada não vazia 
 { 
 pc->EmpilhaPC(pe->ConsultaTopoPE()); 
 pe->DesempilhaPE(); 
 } 
 delete pe;//desaloca a pilha encadeada 
}; 
 Exercício 2: 
 Desenvolver um procedimento querealize a 
transformação inversa da anterior, isto é, 
transforme uma pilha contígua com no máximo 500 
nós (reais) em uma pilha encadeada. 
Pilhas 
25 
Representação por contiguidade dos nós 
 Uma fila contígua onde já ocorreram (n + 1) 
entradas e k saídas de nós, teria a seguinte 
representação esquemática: 
Filas 
26 
 Assim, o TAD TFilaCont de elementos reais 
poderia ser: 
 
0 1 . . . k - 1 k k + 1 . . . n - 1 n n + 1 . . . m-1 
 
 X = - - . . . - NOk NOk + 1 . . . NOn - 1 NOn - . . . - 
 
 c f 
 k n 
 
 Sendo c o índice do vetor que contem o nó do 
começo da fila e f o índice do nó que está no fim. 
TAD TFilaCont 
Filas 
27 
class TFilaCont 
{ 
 private: 
 int m; // capacidade máxima de elementos do vetor 
 int c,f;// índices dos Nos que estão no início e 
 // no fim da fila 
 float *X; // vetor que armazena a fila 
 public: 
 TFilaCont(int tam); 
 float ConsultaInicioFC(); // consulta No do início 
 void EntraFC(float val); // insere No no fim
 
 void SaiFC(); // elimina No do início 
 bool VaziaFC(); // verifica se fila está vazia 
 ~TFilaCont(); 
}; 
 
0 1 . . . k - 1 k k + 1 . . . n - 1 n n + 1 . . . m-1 
 
 X = - - . . . - NOk NOk + 1 . . . NOn - 1 NOn - . . . - 
 
 c f 
 k n 
 
 Construtor: 
Filas 
28 
TFilaCont::TFilaCont(int tam) 
{ 
 m = tam; 
 c = 0; 
 f = -1; 
 X = new float[m]; 
} 
MI do TAD TFilaCont 
 As atribuições c = 0 e f = -1, criam uma fila 
contígua. Mas, se ocorrerem n entradas e n 
saídas, a fila ficará vazia e c = n e f = n-1. Assim, a 
condição de fila contígua vazia é c > f. 
Filas 
29 
float TFilaCont::ConsultaInicioFC() 
{ 
 if(c <= f) 
 return X[c]; 
 else 
 { 
 cout << “Fila vazia!” << endl; 
 exit(1); 
 } 
} 
 Operação ConsultaInicioFC: 
MI do TAD TFilaCont 
Filas 
30 
void TFilaCont::EntraFC(float val); 
{// insere No contendo val no fim da Fila
 
 if(f == (m – 1)) 
 { 
 cout <<"Fila no fim do Vetor!" << endl; 
 exit(2); 
 } 
 f = f + 1; 
 X[f] = val; 
} 
 Operação EntraFC: 
MI do TAD TFilaCont 
Filas 
31 
void TFilaCont::SaiFC() 
{ // elimina No do início da fila
 
 if(c > f) 
 { 
 cout << “Fila Vazia!” << endl; 
 exit(3); 
 } 
 c = c + 1; 
} 
 Operação SaiFC: 
MI do TAD TFilaCont 
Filas 
32 
bool TPilhaCont::VaziaPC() 
{ // verifica se fila está vazia 
 
 if(c > f) 
 return(true); 
 else 
 return(false); 
} 
 Operação VaziaFC: 
MI do TAD TFilaCont 
 Destrutor: 
TFilaCont::~TFilaCont() 
{ 
 delete [] X; 
} 
 Obs.: da forma como foram criadas as operações 
EntraFC e SaiFC, se forem executadas m 
entradas e um determinado número de saídas, a 
fila caminha para o final do vetor, ficando com o 
seguinte aspecto: 
Filas 
33 
 Neste caso, não é possível proceder mais 
entradas na fila, embora hajam posições 
desocupadas no início do vetor. 
 
0 1 . . . i - 1 i i + 1 . . . m-1 
 
 NO = - - . . . - NOi NOi + 1 . . . NOm-1 
 
 C F 
 i m-1 
 
Filas 
34 
1. Alterar a operação EntraFC para deslocar todos os 
elementos da fila para o início do vetor, 
permitindo novas entradas . 
2. Alterar a operação SaiFC de forma que, toda vez 
que ocorrer uma saída (C = 0), a fila seja deslocada 
de uma posição, ficando sempre no início do vetor . 
 As soluções mais comuns para este problema são: 
 
0 1 . . . i - 1 i i + 1 . . . m-1 
 
 NO = - - . . . - NOi NOi + 1 . . . NOm-1 
 
 C F 
 i m-1 
 
 Exercícios: 
Filas 
35 
3. Desenvolver cada uma das operações (EntraFC e 
SaiFC), adotando as soluções sugeridas 
anteriormente. 
4. Qual das duas soluções é a mais eficiente? 
5. Após a realização de cada uma das alterações do 
exercício 3, verificar quais das demais operações 
deveriam ser também alteradas, no sentido de 
melhorar o desempenho geral do TAD TFilaCont. 
 As soluções mais comuns para este problema são: 
Filas 
36 
3. Adotar o conceito de fila circular: 
Onde n é o número 
de nós da fila. 
Nom-1 
NOi 
NOi+1 
0 1 
2 
i-2 
i-1 i 
i+1 
m-1 
c 
i 
f 
m-1 
n 
f – c + 1 
 O TAD TFilaContCirc poderia ser: 
Filas 
37 
class TFilaContCirc 
{ 
 private: 
 int m; // capacidade máxima de elementos do vetor 
 int c,f,n; // índices dos Nos do começo e do fim 
 // da fila e o número atual de Nos 
 float *X; // vetor que armazena a fila 
 int Inc(int ind);//incrementa o índice da fila 
 public: 
 TFilaContCirc(int tam); 
 float ConsultaInicioFCC();// consulta No do início 
 void EntraFCC(float val); // insere No no fim
 
 void SaiFCC(); // elimina No do início 
 bool VaziaFCC(); // verifica se fila está vazia 
 ~TFilaContCirc(); 
}; 
Filas 
38 
 Exercício: 
6. Desenvolver o MI do TAD TFilaContCirc anterior. 
Representação por encadeamento dos nós 
 Esquematicamente, seja uma fila encadeada com 
n nós: 
Filas 
39 
 Neste caso, deve-se também definir dois TAD’s: 
No e TFilaEncad. 
c f 
Filas 
40 
class No 
{ 
 private: 
 float info; // informação real do No 
 No *prox; // ponteiro para o próximo No 
 public: 
 No(); 
 void atribInfo(float val); 
 void atribProx(No *p); 
 float consultaInfo(); 
 No *consultaProx(); 
 ~No(); 
}; 
Representação por encadeamento dos nós 
 TAD No (Definição  No.h): 
Filas 
41 
No::No() {} 
 
void No::atribInfo(float val) { info = val; } 
 
void No::atribProx(No *p) { prox = p; } 
 
float No::consultaInfo() { return info; } 
 
No *No::consultaProx() { return prox; } 
 
No::~No() {} 
Representação por encadeamento dos nós 
 MI do TAD No (Definição  No.h): 
Filas 
42 
class TFilaEncad 
{ 
 private: 
 No *c, *f; // ponteiros para os Nos extremos 
 public: 
 TFilaEncad(); 
 float ConsultaInicioFE(); 
 void EntraFE(float val); // insere No no fim
 
 void SaiFE(); // elimina No do início da fila 
 bool VaziaFE(); // verifica se fila está vazia 
 ~TFilaEncad(); 
}; 
TAD TFilaEncad 
c f 
 Construtor: 
Filas 
43 
TFilaEncad::TFilaEncad() 
{ 
 c = NULL; 
 f = NULL; 
} 
MI do TAD TFilaEncad 
Condição de fila encadeada vazia: 
c = NULL e/ou f = NULL 
Filas 
44 
 Operação ConsultaInicioFE: 
float TFilaEncad::ConsultaInicioFE() 
{ 
 if(c != NULL) 
 return c->consultaInfo(); 
 else 
 { 
 cout << “Fila vazia!” << endl; 
 exit(1); 
 } 
} 
MI do TAD TFilaEncad 
Filas 
45 
 Operação EntraFE: 
void TFilaEncad::EntraFE(float val);
 
{ // insere No contendo val no fim da fila 
 No *p = new No(); // cria No apontado por p 
 p->atribInfo(val); // preenche info com val 
 p->atribProx(NULL); // prox recebe NULL 
 if(f == NULL) 
 c = p; // inserção do primeiro No 
 else 
 f->atribProx(p);//liga No apontado por p a fila 
 f = p; //No apontado por p passa a ser o último 
} 
MI do TAD TFilaEncad 
Filas 
46 
 Operação SaiFE: 
void TFilaEncad::SaiFE() 
{ // elimina No do início da fila
 
 No *p; 
 if(c != NULL){ // se fila não está vazia 
 p = c; // p aponta para o No a ser excluído 
 c = p->consultaProx();//cpassa a apontar para 
 //o atual segundo No 
 if(c == NULL) 
 f = NULL; // a fila esvaziou 
 delete p;} // exclui o No do início 
 else 
 Rotina_Erro(1); 
} 
MI do TAD TFilaEncad 
Filas 
47 
bool TFilaEncad::VaziaFE() 
{ // verifica se fila está vazia 
 
 if(c == NULL) 
 return(true); 
 else 
 return(false); 
} 
 Operação VaziaFE: 
MI do TAD TFilaEncad 
Filas 
48 
 Destrutor: 
TFilaEncad::~TFilaEncad() 
{ 
 No *p = c; 
 while(c != NULL) 
 { 
 c = p->consultaProx(); 
 delete p; 
 p = c; 
 } 
 f = NULL; 
} 
MI do TAD TFilaEncad 
Aplicações 
1. Desenvolver um procedimento para inverter o 
sentido de uma fila representada por uma lista 
encadeada. 
2. Considerando uma pilha representada por lista 
encadeada onde cada nó possui um valor real, 
desenvolver um procedimento para 
desempilhar os seus nós montando uma lista 
circular (duplamente encadeada). 
Pilhas e Filas 
49 
Aplicações 
3. O gerente de desenvolvimento de aplicações de 
uma empresa observou que diversos 
programas trabalham com filas encadeadas 
que devem ser gravadas em memória auxiliar. 
Para isso é necessário representar a fila 
contiguamente. Desenvolver um procedimento 
para fazer esta transformação sabendo que 
cada nó possui um valor real e que uma fila 
possui no máximo 500 nós. 
Pilhas e Filas 
50 
Aplicações 
4. Desenvolver um procedimento para fazer a 
transformação inversa da anterior. 
5. Desenvolver um procedimento para montar 
duas filas contíguas, sendo que uma deve 
conter somente números inteiros negativos e a 
outra, os demais números. Os números inteiros 
serão fornecidos através de uma pilha 
encadeada em que cada nó possui um número 
inteiro e qualquer. Considerar que a pilha 
possui no máximo 100 nós. 
Pilhas e Filas 
51 
Aplicações 
6. Desenvolver um PA para ler diversos valores X 
inteiros e montar uma fila encadeada, usando o 
TAD TFilaEncad e atendendo as seguintes 
características: 
a) O último valor a ser lido é um FLAG com X = 0. 
b) Na fila só podem entrar nós com X > 0 e maior 
que a informação X do último nó já incluído 
na fila. 
c) Toda vez que for lido um valor X < 0, retirar 
um nó da fila, desde que ela não esteja vazia. 
d) No final, imprimir todos os nós da fila. 
Pilhas e Filas 
52

Continue navegando

Outros materiais