You are on page 1of 18

FEUP/LEEC Algoritmos e Estruturas de Dados 2001/2002

Pilhas e Filas

Joo Canas Ferreira http://www.fe.up.pt/~jcf

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

#1

Contedo
1. Pilhas (a) Implementao baseada em listas (b) Implementao baseada em vectores 2. Filas (a) Implementao baseada em listas (b) Implementao baseada em vectores 3. Aplicaes de pilhas (a) Clculo de expresses RPN (b) Converso de expresses inxas para RPN 4. Aplicao de las (a) Percurso mais curto num labirinto

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

#2

Pilhas

Pilha Estrutura de dados em que a insero e a remoo de elementos de uma sequncia se faz pela mesma extremidade, geralmente designada por topo da pilha. Uma pilha pode ser considerada como uma restrio de lista. Visto que se trata de uma estrutura de dados mais simples que a lista, possvel obter implementaes mais ecazes. O conceito de iterador no se aplica a esta estrutura de dados. LIFO = Last-in First-out

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

#3

Operaes com pilhas


1 2 3 4 5 5 1 2 3 4 5 3 2 1 1 2 1 4 3 2 1 4 3 2 1

5 4 3 2 1 4 3 2 1 3 2 1 2 1 1 5 4 3 2 1

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

#4

Pilha Implementao baseada em listas


template <class T> class LStack { public: LStack(); LStack(const LStack &stk); ~LStack(); bool isEmpty() const; bool isFull() const; const T & top() const; void makeEmpty(); void pop(); void push(const T &x); T topAndPop(); const LStack & operator=(const LStack &stk); ///... Pilhas e Filas #5

FEUP/LEEC,AED,2001/2002, v0.1

Classe LStack Seco privada


template <class T> class LStack { // ... private: class ListNode // classe privada { public: T element; ListNode *next; ListNode(const T & elem, ListNode *n = 0) : element(elem), next(n) { }; }; ListNode *topOfStack; };

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

#6

push() e top()

template <class T> void LStack<T>::push(const T &x) { topOfStack = new ListNode(x, topOfStack); } template <class T> const T & LStack<T>::top() const { if (isEmpty()) throw Underflow(); return topOfStack->element; }

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

#7

pop() e topAndPop()
template <class T> void LStack<T>::pop() { if (isEmpty()) throw Underflow(); ListNode *oldTop = topOfStack; topOfStack = topOfStack->next; delete oldTop; } template <class T> T LStack<T>::topAndPop() { T topItem = top(); pop(); return topItem; }

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

#8

PilhasImplementao baseada em vectores

template <class T> class VStack { public: explicit VStack(int capacity = 100); bool isEmpty() const; bool isFull() const; const T & top() const; void makeEmpty(); void pop(); void push(const T &x); T topAndPop(); //...

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

#9

VStack Seco privada


template <class T> class VStack { // ... private: vector<T> theArray; int topOfStack; };

Ateno: No deixar o vector aumentar de tamanho.


topOfStack =3 VAZIO

topOfStack = -1

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 10

Classe VStack Implementao


template <class T> bool VStack<T>::isFull() const { return topOfStack == theArray.size() - 1; } template <class T> void VStack<T>::makeEmpty() { topOfStack = -1; } template <class T> void VStack<T>::push(const T &x) { if (isFull()) throw Overflow(); theArray[++topOfStack] = x; }

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 11

Classe VStack pop() e top()


template <class T> const T & VStack<T>::top() const { if (isEmpty()) throw Underflow(); return theArray[topOfStack]; } template <class T> void VStack<T>::pop() { if (isEmpty()) throw Underflow(); topOfStack--; } template <class T> T VStack<T>::topAndPop() { if (isEmpty()) throw Underflow(); return theArray[topOfStack--]; } Pilhas e Filas # 12

FEUP/LEEC,AED,2001/2002, v0.1

Filas

Fila Estrutura de dados em que a insero e a remoo de elementos de uma sequncia se faz por extremidades opostas, geralmente designadas por cabea e cauda da la. Uma la pode ser considerada como uma restrio de lista. Visto que se trata de uma estrutura de dados mais simples que a lista, possvel obter implementaes mais ecazes. O conceito de iterador no se aplica a esta estrutura de dados. FIFO = First-in First-out

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 13

Funcionamento de las
12345 1 1 2 3 4 5

5 1 2 3 4 5

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 14

Filas Implementao com listas

LQueue<char> back front

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 15

Classe LQueue seco pblica


template <class T> class LQueue { public: LQueue(); LQueue(const LQueue &stk); ~LQueue(); bool isEmpty() const; bool isFull() const; const T & getFront() const; void makeEmpty(); void dequeue(); void enqueue(const T &x); const LQueue & operator=(const LQueue &stk); // ... }; Pilhas e Filas # 16

FEUP/LEEC,AED,2001/2002, v0.1

Classe LQueue seco privada


template <class T> class LQueue { // ... private: class ListNode { public: T element; ListNode *next; ListNode(const T & elem, ListNode *n = 0) : element(elem), next(n) { }; }; ListNode *front, *back; };

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 17

Classe LQueue enqueue() e dequeue


template <class T> void LQueue<T>::enqueue(const T &x) { ListNode *oldBack = back; back = new ListNode(x, 0); if (oldBack) oldBack->next = back; if (!front) front = back; } template <class T> void LQueue<T>::dequeue() { if (isEmpty()) throw Underflow(); ListNode *oldFront = front; front = front->next; delete oldFront; if (!front) back = 0; } Pilhas e Filas # 18

FEUP/LEEC,AED,2001/2002, v0.1

Filas Implementao com vectores


Importante: Evitar deslocar os elementos do vector.
tirar a a b c d back colocar e tirar b b c d e back colocar f tirar c f c d e f d e c d e b c d back

front

front

front

front

back

back

front

back

front

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 19

Classe CQueue seco privada


template <class T> class CQueue { public: explicit CQueue(int capacity = 100); // ... private: vector<T> theArray; int currentSize; int front, back; void increment(int &x); };

O campo currentSize no estritamente necessrio, mas facilita bastante a gesto da estrutura. Nota: No se permite a extenso do vector.
Pilhas e Filas # 20

FEUP/LEEC,AED,2001/2002, v0.1

10

Classe CQueue enqueue() e dequeue()


template <class T>void CQueue<T>::enqueue(const T &x) { if (isFull()) throw Overflow(); increment(back); theArray[back] = x; currentSize++; } template <class T> void CQueue<T>::increment(int &x) { if (++x == theArray.size()) x = 0; } template <class T> T CQueue<T>::dequeue() { if (isEmpty()) throw Underflow(); currentSize--; int oldFront = front; increment(front); return theArray[oldFront]; } Pilhas e Filas # 21

FEUP/LEEC,AED,2001/2002, v0.1

Notao RPN
Notao RPN: Expresses aritmticas em que os operadores surgem a seguir aos operandos (notao ps-xa). RPN=Reverse Polish Notation Notao inxa: Os operadores binrios surgem entre os operandos. Notao inxa: 2 * ( 4 + 5 ) / 3 Notao RPN: 2 4 5 + * 3 / Vantagens de RPN: No requer parnteses nem regras de precedncia.

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 22

11

Avaliao de expresses RPNExemplo


Uma expresso RPN facilmente avaliada com a ajuda de uma pilha.
2 4 5 + * 3 / 2 4 5 + * 3 / 2 4 5 + * 3 / 2 4 5 + * 3 / 2 4 5 + * 3 / 2 4 5 + * 3 / 2 4 5 + * 3 /

5 4 2 2 4 2 9 2 18 3 18 6

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 23

Avaliao de expresses RPNAlgoritmo


1. Processar sequencialmente os elementos da expresso. Para cada elemento: (a) Se o elemento for um nmero, coloc-lo na pilha; (b) Se for um operador i. Retirar os dois elementos do topo da pilha; ii. Processar os elementos de acordo com o operador; iii. Colocar o resultado na pilha. 2. Retirar o (nico) elemento da pilha: o resultado. (Ver tb. seco 3.3.3 de [DSAA].)

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 24

12

Especicao de um programa para avaliar expresses RPN

1. Ler expresses de cin; 2. Os elementos da expresso so separados por espaos e terminadas com =; 3. Escrever os resultados em cout; 4. Ignorar linhas vazias; 5. Terminar com m-de-cheiro (^D em Unix, ^Z em Windows)

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 25

Converso entre notao inxa e RPN


A converso entre notao inxa e RPN tambm pode ser feita com o recurso a uma pilha. A pilha usada para guardar os operadores pendentes; quando surge um operador todos os operadores de maior ou igual precedncia so retirados da pilha. Quando surge um ) esvazia-se a pilha at encontrar o primeiro (. Prioridades: ( / * + -

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 26

13

2*(4+5)/3; 2*(4+5)/3; 2*(4+5)/3; 2*(4+5)/3; 2*(4+5)/3; 2*(4+5)/3; 2*(4+5 ) / 3; 2*(4+5) / 3; 2*(4+5) / 3 ; 2*(4+5)/3 ;

+ ( * Sada: 2 4 5 * ( * ( *

+ ( * * + / * 3 / / =

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

Especicao do programa de converso


1. Ler expresses de cin; 2. Os elementos da expresso so separados por espaos e terminadas com ponto-e-vrgula; 3. Escrever os resultados em cout, terminados com =; 4. Ignorar linhas vazias; 5. Terminar com m-de-cheiro (^D em Unix, ^Z em Windows) Os dois programas anteriores podem ser combinados em Unix: # i2r | postfix 2 * ( 3 + 4 ) ; 14 ^D
FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

14

Exemplo de converso inxo

RPN

# 27

# 28

Percurso mais curto Algoritmo de Lee


Como encontrar o percurso mais curto entre dois pontos de um labirinto?
1 1 2 3 4 5 6 7 2 3 4 5 6 7 1 2 1 2 3 4 5 6 7

3 2 1 2

2 1 a 1 2 1 2 3 4 5 6 6 7 2 b 8 7 8 9 8 9

3 2 1 2

2 1 a 1 2 1 2 3 4 5 6 6 7 2 b 8 7 8 9 8 9

3 4 5 6 7

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 29

Algoritmo de Lee
1. Numerar todos os vizinhos do ponto inicial com 1. 2. Colocar os vizinhos numa la. 3. Enquanto a la no estiver vazia e no se tiver atingido o ponto de destino: (a) Retirar um ponto da la; (b) Numerar os seus vizinhos livres com o nmero do ponto acrescido de 1; (c) Colocar os novos pontos (vizinhos) na la 4. Se a la estiver vazia e no se tiver atingido o ponto de destino, no existe percurso. Caso contrrio, escrever o percurso em cout.

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 30

15

Especicao do labirinto
1 2 3 4 5 6 7 8 9 10 11 12

12 12 0 0 0 0 0 1 1 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 0 0 0 0 (1,1)

1 1 1 1 1 1 0 0 0 1 0 0 1 1 1 0 1 1 0 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 (10,2)

0 0 0 0 0 1 0 1 1 1 0 0

0 0 1 1 0 0 0 0 1 1 0 0

0 0 1 1 1 0 0 0 0 0 0 0

1 0 0 0 0 0 0 1 0 0 1 1

1 1 0 0 0 0 0 1 1 0 1 0

1 2 3 4 5 6 7 8 9 10 11 12

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 31

Especicao do programa

1. Ler um cheiro com: dimenso do labirinto;


zonas livres e ocupadas; pontos inicial e nal.

2. Fazer vericaes de consistncia; 3. Aplicar algoritmo de Lee; 4. Imprimir percurso em cout.

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 32

16

Representao interna do labirinto


1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 0 1 0 1 0 0 0 1 1 0 0 1 1 1 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1
1 2 3 4 5 6 7 1 2 3 4 5 6 7

FEUP/LEEC,AED,2001/2002, v0.1

Pilhas e Filas

# 33

Pontos e clculo da vizinhana


class Ponto { public: int linha, coluna; Ponto(int li = 0, int col = 0) : linha(li), coluna(col) { }; bool operator==(const Ponto &pt) const { return (linha == pt.linha) && (coluna == pt.coluna);} }; // Clculo de vizinhana const int n_viz = 4; int delta_linha[n_viz] = { 0, 1, 0, -1 }; int delta_coluna[n_viz] = { 1, 0, -1, 0 }; //... for (int i = 0; i < n_viz; i++) { vizinho.linha = corrente.linha + delta_linha[i]; vizinho.coluna = corrente.coluna + delta_coluna[i]; // ... Pilhas e Filas # 34

FEUP/LEEC,AED,2001/2002, v0.1

17

Determinao do percurso
Ponto *percurso = new Ponto [comprimento_percurso]; // refazer o percurso do ponto final para o inicial corrente = fim; for (int j = comprimento_percurso -1; j >= 0; j--) { percurso[j] = corrente; // encontrar predecessor for (int i = 0; i < n_viz; i++) { vizinho.coluna = corrente.coluna + delta_coluna[i]; vizinho.linha = corrente.linha + delta_linha[i]; if (grelha[vizinho.linha][vizinho.coluna] == j + 2) break; } corrente = vizinho; } Pilhas e Filas # 35

FEUP/LEEC,AED,2001/2002, v0.1

18

You might also like