Pilhas Profa. Nádia Félix
Definição Uma pilha é uma coleção de objetos que são inseridos e retirados de acordo com o princípio de que o último que entra é o primeiro que sai (LIFO – LAST-IN, FIRST-OUT). É possível inserir objetos em uma pilha a qualquer momento, mas somente o objeto inserido mais recentemente (o último que entrou) pode ser removido a qualquer momento.
Definição O nome “pilha” deriva-se da metáfora de uma pilha de pratos em uma cantina. Retira-se o prato do topo da pilha (pop); Coloca-se o prato na pilha (push)
As pilhas são uma estrutura de dados fundamental: elas são usadas em muitas aplicações, como por exemplo: Navegadores para a Internet armazenam os endereços mais recentemente visitados em uma pilha. Cada vez que o navegador visita um novo site, o endereço do site é armazenado na pilha de endereços. O navegador permite que o usuário retorne o site previamente visitados (“pop”) usando o botão “back”. Editores de texto geralmente oferecem um mecanismo de reversão de operações (“undo”) que cancela operações recentes e reverte um documento a estados anteriores. A operação de reversão é implementada mantendo-se as alterações no texto em uma pilha.
O tipo abstrato de dados Pilha Pilhas são as mais simples de todas estruturas de dados, apesar de estar entre uma das mais importantes.
O tipo abstrato de dados Pilha Formalmente, uma pilha S é um tipo abstrato de dados (TAD) que suporta os dois métodos que seguem: push(e): insere o objeto e no topo da pilha. pop( ): remove o elemento no topo da pilha e o retorna; ocorre um erro se a pilha estiver vazia. Adicionalmente, podem-se definir os seguintes métodos: size ( ): retorna o número de elementos na pilha. isEmpty( ): retorna um booleano indicando se a pilha está vazia. top( ): retorna o elemento no topo da pilha, sem retirá-lo; ocorre um erro se a pilha estiver vazia.
Exemplo: A tabela a seguir mostra uma série de operações de pilha e seus efeitos sobre uma pilha S de inteiros, inicialmente vazia Operação Saída Conteúdo da pilha push(5) - (5) push(3) (5,3) pop() 3 push(7) (5,7) 7 top() 5 () “error” isEmpty() true push(9) (9) (9,7) (9,7,3) (9,7,3,5) size() 4 push(8) (9,7,3,8)
Pilha- em Java A estrutura de dados pilha é uma classe “embutida” no pacote java.util.Stack Inclui entre outros, os métodos push(), pop(), peek() (equivalente ao método top()), size() e empty() (equivalente a isEmpty()). Os métodos pop() e peek() lançam a exceção EmptyStackException se a pilha estiver vazia quando eles forem chamados. Embora seja conveniente usar a classe java.util.Stack, é instrutivo aprender como projetar e implementar uma pilha desde o início.
Uma interface para Pilhas em Java Implementar um tipo abstrato de dados em Java envolve dois passos: Definição de uma Application Programming Interface (API), ou simplesmente interface que descreve os nomes dos métodos que o TAD suporta e como eles são declarados e usados. Definir exceções para qualquer condição de erro que possa ocorrer. Por exemplo: A condição de erro que ocorre quando se chama os métodos pop() ou top() sobre uma pilha vazia é sinalizada pelo lançamento de uma exceção do tipo EmptyStackException
Definindo Exceção A condição de erro que ocorre quando se chama os métodos pop( ) ou top( ) sobre uma pilha vazia é sinalizada pelo lançamento de uma exceção do tipo EmptyStackException. public class EmptyStackException extends RuntimeException{ public EmptyStackException(String err){ super(err); }
Definindo a Interface da Pilha public interface interfStack<E> { /** * Retorna o número de elementos da pilha * @return número de elementos na pilha. */ public int size(); * Indica quando a pilha está vazia * @return true se a pilha é vazia, false em caso contrário public boolean isEmpty(); * Inspeciona o elemento no topo da pilha * @return o elemento do topo da pilha. * @exception EmptyStackException se a pilha estiver vazia.
public E top() throws EmptyStackException; / public E top() throws EmptyStackException; /** * Insere um elemento no topo da pilha. * @param elemento a ser inserido. */ public void push(E element); * Remove o elemento do topo da pilha. * @return elemento a ser removido. * @exception EmptyStackException se a * pilha estiver vazia. public E pop() }
Uma Implementação baseada em Arranjos A pilha desta implementação necessita: Um Arranjo S de N elementos; Uma variável t, que fornece o índice do elemento topo no arranjo S; t = -1, pilha vazia. Uma nova exceção (específica para esta implementação) chamada FullStackException, que sinalizará uma condição de erro ao se tentar inserir um novo elemento em um arranjo cheio. Observação: t pode ser usada para calculo do size t+1 S 1 2 t … N-1
Classe FullStackException public class FullStackException extends RuntimeException { public FullStackException(String err) { super(err); }
Implementação de uma pilha através de um arranjo de tamanho fixo, N Algoritmo size() return t + 1 Algorithm pop() if isEmpty() then throw EmptyStackException else t t 1 return S[t + 1] -São adicionados elementos da esquerda para direita Uma variável controla o índice do elemento do topo … S 1 2 t
Implementação de uma pilha através de um arranjo de tamanho fixo, N Algorithm push(o) if t = S.length 1 then throw FullStackException else t t + 1 S[t] o -O array que armazena os objetos pode ficar cheio. Uma operação push poderá lançar uma exceção FullStackException. … S 1 2 t
Implementação da interface interfStack public interface interfStack<E> { /** * Retorna o número de elementos da pilha * @return número de elementos na pilha. */ public int size(); * Indica quando a pilha está vazia * @return true se a pilha é vazia, false em caso contrário public boolean isEmpty(); * Inspeciona o elemento no topo da pilha * @return o elemento do topo da pilha. * @exception EmptyStackException se a pilha estiver vazia.
public E top() throws EmptyStackException; /** * Insere um elemento no topo da pilha. * @param elemento a ser inserido. */ public void push(E element); * Remove o elemento do topo da pilha. * @return elemento a ser removido. * @exception EmptyStackException se a * pilha estiver vazia. public E pop() }
Implementação da interface da Pilha public class ArrayStack<E> implements interfStack<E>{ protected int capacidade; //capacidade real do arranjo da pilha public static final int CAPACIDADE = 1000; //capacidade padrão do arranjo protected E S[]; //Arranjo genérico usado para implementar a pilha protected int topo = -1; //índice para o topo da pilha public ArrayStack(){ this(CAPACIDADE); //capacidade padrão } public ArrayStack(int cap){ capacidade = cap; S = (E[])new Object[capacidade];
public int size(){ return (topo + 1); } public boolean isEmpty(){ return (topo<0); public void push(E elemento) throws FullStackException { if(size()==capacidade){ throw new FullStackException("Pilha está Cheia!"); S[++topo] = elemento; public E top() throws EmptyStackException{ if(isEmpty()) throw new EmptyStackException("Pilha está Vazia!"); return S[topo];
public E pop() throws EmptyStackException{ E elemento; if(isEmpty()) throw new EmptyStackException("Pilha está Vazia!“); elemento = S[topo]; S[topo--]=null; return elemento; } public String toString(){ String s; s = " ["; if(size()>0) s+=S[0]; if(size()>1) for(int i = 1; i<=size()-1;i++){ s+= ", "+S[i]; return s + "]";
public void status(String op, Object elemento){ //imprime esta operação System.out.print("--------> "+op); //o que foi retornado System.out.println(" , retorna "+elemento); System.out.print("resultado: tamanho = " + size()+ " , Pilha Vazia? "+isEmpty()); //conteúdo da pilha System.out.println(", pilha: "+this); }