UFABC
Universidade Federal do ABC
Aula 04
Contedo
Pilhas
Sequencial Encadeada Aplicaes
Introduo
Estruturas de
dados
Para explicar esse conceito, partimos do princpio que todo algoritmo manipula dados (entrada e sada)
Uma estrutura de dados consiste em um meio de se armazenar dados com o objetivo de facilitar ao algoritmo:
Receber novos dados Encontrar dados que ele precise em um determinado momento
Se livrar de dados no mais relevantes
Introduo
Estruturas de
dados
Estas mesmas operaes bsicas so aplicadas grande maioria das estruturas, porm elas funcionam de maneira diferente. Exemplo: qual a diferena entre enfileirar e empilhar?
4
Introduo
Estruturas de
dados
Uma estrutura de dados pode ser projetada para armazenar dados em diversas meios de armazenamento:
Disco
Fita
Introduo
Estruturas de
Mtodos de implementao
Sequencial
Encadeado
Uma pilha sequencial uma ED implementada em cima de um vetor de dados. Os elementos da pilha ocuparo posies contguas de memria, por isso o termo senquencial. As duas principais operaes so
Empilha / Push Desempilha / Pop
Pilha sequencial
Pilha sequencial
. . . 1 0
9
Pilha sequencial
. . . 1 0
10
Pilha sequencial
. . . 1 0
11
Pilha sequencial
. . . 1 0 topo
12
Pilha sequencial
. . . 1 topo 0
13
Pilha sequencial
. . . 1 topo 20 0
14
Pilha sequencial
. . . 1 topo 20 0
15
Pilha sequencial
. . . topo 30 20 1 0
16
Pilha sequencial
topo
40 30 20
. . . 1 0
17
Pilha sequencial
100 90 80 70 60 50 40 30 20
n-1
verificao inicial:
topo == n-1 ?
. . . 1 0
18
Se sim, a pilha deve avisar o utilizar por meio de algum mecanismo que a pilha est cheia
Pilha sequencial
Mecanismo de excees:
throw logic_error("Pilha cheia");
As excees so a melhor forma de se comunicar algo ao utilizador da classe. Vamos procurar sempre utilizar excees
19
Pilha sequencial
n-1
Pilha sequencial
100
n-1
topo
90 80 70 60 50 40 30 20 . . . 1 0
21
Pilha sequencial
topo
80 70 60 50 40 30 20 . . . 1 0
22
Pilha sequencial
Pilha sequencial
PilhaSeq.h
// Mtodos principais void empilha(int elem); int desempilha(); // Mtodos auxiliares bool cheia(); bool vazia(); int tamanho(); private: int *vetor; int topo, size; };
24
Pilha sequencial
PilhaSeq.h
// Mtodos principais void empilha(const Tipo &elem); Tipo desempilha(); // Mtodos auxiliares bool cheia(); bool vazia(); int tamanho(); private: Tipo *vetor; int topo, size; };
25
Pilha sequencial
PilhaSeq.h
// Mtodos principais void empilha(const Tipo &elem) throw (logic_error); Tipo desempilha() throw (logic_error); // Mtodos auxiliares bool cheia(); bool vazia(); int tamanho(); private: Tipo *vetor; int topo, size; };
26
Pilha sequencial
Implementaes
// Construtor template <typename Tipo> PilhaSeq<Tipo>::PilhaSeq(int size) { this->size = size; vetor = new Tipo[size]; topo = -1; }
PilhaSeq.h
27
Pilha sequencial
Implementaes
PilhaSeq.h
28
Pilha sequencial
Implementaes
PilhaSeq.h
// Empilha template <typename Tipo> void PilhaSeq<Tipo>::empilha(const Tipo &el) throw (logic_error){ if (topo == (size-1)) throw logic_error("Pilha cheia"); vetor[++topo] = el; }
29
Pilha sequencial
Implementaes
PilhaSeq.h
// Desempilha template <typename Tipo> Tipo PilhaSeq<Tipo>::desempilha() throw (logic_error) { if (topo < 0) throw logic_error("Pilha vazia"); return(vetor[topo--]); }
30
Pilha sequencial
Implementaes
// Mtodos auxiliares template <typename Tipo> bool PilhaSeq<Tipo>::cheia() { return(topo == (size-1)); }
PilhaSeq.h
template <typename Tipo> bool PilhaSeq<Tipo>::vazia() { return(topo <0); } template <typename Tipo> int PilhaSeq<Tipo>::tamanho() { return(topo + 1); }
31
Pilha sequencial
Demais informaes
#ifndef _PilhaSeq_H #define _PilhaSeq_H #include <stdexcept.h>
Inclusion Guards Biblioteca para excees Para utilizar a classe logic_error Para organizao
PilhaSeq.h
using std::logic_error;
namespace ED {
Pilha sequencial
Main.cpp
int main(int argc, char** argv) { PilhaSeq<int> p(30); for (int i=0; i<20; i++) p.empilha(i); for (int i=0; i<20; i++) cout << p.desempilha() << endl;
}
33
Pilha sequencial
Main.cpp
Aqui, o utilizador no est interessado em receber mensagens da pilha. Tudo bem, ele no obrigado, mas se ele quiser, ele pode: try...catch
int main(int argc, char** argv) { PilhaSeq<int> p(30); for (int i=0; i<20; i++) p.empilha(i);
for (int i=0; i<20; i++) cout << p.desempilha() << endl;
}
34
Pilha sequencial
using ED::PilhaSeq;
Main.cpp
int main(int argc, char** argv) { PilhaSeq<int> p(30); try { for (int i=0; i<20; i++)
p.empilha(i);
for (int i=0; i<20; i++) cout << p.desempilha() << endl; } catch (logic_error err){ cout << err.what(); } }
35
Pilha sequencial
36
int main(int argc, char** argv) { PilhaSeq<Ponto2D> p(50); Ponto2D pt; for (int i=0; i<5; i++) for (int j=0; j<5; j++) { pt.x = i; pt.y = j; p.empilha(pt); } for (int i=0; i<25; i++) { pt = p.desempilha(); cout << pt.x << , << pt.y << endl; } }
37
Main.cpp
Pilha sequencial
Onde est alocada a memria sequencial para a pilha do objeto p? Quantos bytes utilizado na memria sequencial para a pilha do objeto p? O que acontece se fizermos
Ponto2D p1, p2;
p1.x=10; p2 = p1;
38
Pilha sequencial
39
Pilha sequencial
criao
Se a pilha est com poucos elementos, muita memria estar sendo alocada desnecessariamente
Se a pilha est quase cheia, ento, provavelmente, ela ir encher em breve, e no poderemos mais inserir elementos
40
Pilha sequencial
outro caso:
Memria sub utilizada Falta de espao
41
Pilha encadeada
42
Pilha encadeada
Exemplo
de pilha encadeada:
topo
43
Pilha encadeada
44
Pilha encadeada
ou
Tipo el;
Celula *prox;
45
Pilha encadeada
topo
46
Pilha encadeada
Empilhando um elemento: 10
topo
nova
47
Pilha encadeada
Empilhando um elemento: 10
topo
10
nova
48
Pilha encadeada
Empilhando um elemento: 10
topo
10
nova
49
Pilha encadeada
Empilhando um elemento: 10
Celula *nova = new Celula; nova->el = 10; nova->prox = topo; topo = nova; nelem++;
topo 10
nova
50
Pilha encadeada
Empilhando um elemento: 20
Celula *nova = new Celula; nova->el = 20; nova->prox = topo; topo = nova; nelem++;
topo 20
10
nova
51
Pilha encadeada
Desempilhando
topo 20
10
ret
20
52
Pilha encadeada
Desempilhando
topo 20
10
aux
ret
20
53
Pilha encadeada
Desempilhando
topo
20
10
aux
ret
20
54
Pilha encadeada
Desempilhando
Tipo ret = topo->el; Celula *aux = topo; topo = topo->prox; delete aux; nelem--; return(ret);
topo
10
ret
20
55
Pilha encadeada
Desempilhando
Tipo ret = topo->el; Celula *aux = topo; topo = topo->prox; delete aux; nelem--; return(ret);
topo
ret
10
56
Pilha encadeada
PilhaEnc.h
// Mtodos auxiliares bool vazia(); int tamanho(); private: struct Celula { Tipo el; Celula *prox; };
Celula *topo; int nelem; }; 57
Pilha encadeada
Implementaes
PilhaEnc.h
58
Pilha encadeada
Implementaes
// Destrutor template <typename Tipo> PilhaEnc<Tipo>::~PilhaEnc() { Celula *aux; while (topo) { aux = topo; topo = topo->prox; delete aux; } }
PilhaEnc.h
59
Pilha encadeada
Implementaes
PilhaEnc.h
// Empilha template <typename Tipo> void PilhaEnc<Tipo>::empilha(const Tipo &el) throw (logic_error){ Celula *nova = new Celula;
if (nova == NULL) throw logic_error("Falta memoria\n"); nova->el = el; nova->prox = topo;
60
Pilha encadeada
Implementaes
PilhaEnc.h
if (nelem == 0)
Tipo ret = topo->el; Celula *aux = topo; topo = topo->prox; delete aux; nelem--;
return(ret); }
61
Pilha encadeada
Implementaes
// Mtodos auxiliares
template <typename Tipo> bool PilhaEnc<Tipo>::vazia() { return(nelem == 0); }
PilhaEnc.h
62
64
Nas implementaes apresentadas nestas aulas, os itens de dados so armazenados dentro da memria alocada para a pilha, seja ela sequencial ou encadeada.
Existe tambm a possibilidade de uma implementao onde no so armazenados os dados em si, mas sim, ponteiros para esses itens.
O grande problema desse tipo de implementao fica por conta da desalocao de memria.
65
Exerccios
Implementar:
pilha sequencial
pilha encadeada
66
Exerccios
<-> 3 4 5 + * <-> 3 4 + 7 8 + *
Leia um nmero ou um operador Se for nmero, empilhe Se for operador, desempilhe os ltimos 2 nmeros, realize a operao correspondente e empilhe o resultado
67
Exerccios
. . . x .
. . . x .
. x x . .
. x . . .
x . . . .
. . . x x
. . . x x
. x x x x
. x x x x
x x x x x
68
Exerccios
Algoritmo bsico
empilhe o ponto inicial (xi, yi) enquanto a pilha no estiver vazia desempilha um ponto (x, y)
se (x,y) um ponto vlido e se no estiver pintado (x)
69
Exerccios
3 Implementar um programa para validar uma expresso aritmtica com relao ao balenceamento de () [] e {}
Exemplo:
d^{[(a+b) *c] * [c*(a+d) ^(d+e)]} d^{[(a+b) *c] * c*(a+d) ^(d+e)]} ok errado
70
Exerccios
3 Implementar um programa para validar uma expresso aritmtica com relao ao balenceamento de () [] e {} Algoritmo
Ler um smbolo (letra, operador, um delimitador )
Se for um ( ou um [ ou um { Empilha o smbolo Se for um ) ou um ] ou um } Desempilha um smbolo e compara com o smbolo de entrada
Se forem diferente, retorna errado
Se for igual, continua. Ao trmino da cadeia, se a pilha estiver vazia, retorna correto
71