Pilhas: Fundamentos e implementação da estrutura em Java

Veja neste artigo os fundamentos da estrutura de dados pilha (LIFO), bem como a implementação de uma pilha simples em Java.

Uma questão importante no estudo da computação é o entendimento das estruturas de dados, dentre as quais temos filas, pilhas, listas ligadas, entre outras. Vamos entender aqui o funcionamento das pilhas e como implementar uma pilha simples em Java.

O que é uma estrutura de dados?

A estrutura de dados é o coração de diversos programas bem elaborados, saber qual tipo de estrutura utilizar é essencial para construir um aplicativo de qualidade. A estrutura de dados é na verdade a forma de organizar e armazenar informações para que estas possam posteriormente ser utilizadas de modo eficiente.

O que é uma pilha?

A pilha é uma das estruturas de dados e trabalha com o formato LIFO (o último a entrar é o primeiro a sair, “Last In, First Out”, em inglês). Lembre-se da pilha como uma pilha de livros, em que o primeiro livro que foi inserido na pilha, normalmente é o último que sai dela, enquanto o último adicionado é o primeiro a ser retirado, como vemos na Figura 1.

Figura 1. Pilhas em Java

A estrutura da pilha, segundo Farias “são estruturas de dados do tipo LIFO (last-in first-out), onde o último elemento a ser inserido, será o primeiro a ser retirado. Assim, uma pilha permite acesso a apenas um item de dados - o último inserido. Para processar o penúltimo item inserido, deve-se remover o último”.

A pilha é considerada uma estrutura de dados simples, sendo fácil de implementar. Em uma análise simples, poderia ser utilizada, por exemplo, em um carregamento de um caminhão, pois se o caminhão tiver 4 entregas, a última entrega colocada dentro do caminhão deve ser a primeira a sair, caso contrário, pode dar mais trabalho para descarregar.

Um outro caso de pilha simples de se entender é o caso do entregador de pizza.

O entregador deve entregar três pizzas em locais diferentes, se ele colocar na ordem de entrega, o que vai ocorrer é que a primeira pizza colocada no baú é a primeira pizza a ser entregue, de forma que todas as outras pizzas estão sobre a primeira pizza, então qual a melhor lógica?

Mudar a ordem: a primeira pizza no baú deve ser a última a ser entregue e a última pizza do baú, a primeira a ser entregue. Neste caso, ao chegar na casa do cliente, o entregador apenas pega a primeira pizza que está no baú e entrega ao cliente.

Este exemplo foi proposto inicialmente por Takai, apresentando uma rota de entrega de quatro pizzas, sendo a seguinte ordem:

  1. 1° entrega: Portuguesa
  2. 2° entrega: Frango com catupiry
  3. 3° entrega: Calabresa
  4. 4º entrega: Quatro queijos

Assim, para armazenar no baú, a ordem deve ser invertida, ficando da seguinte forma:

Para as tarefas temos: a criação da pilha, o empilhamento - push (ato de colocar uma caixa de pizza sobre a outra), o ato de desempilhar - pop (na hora que o entregador tira a caixa de pilha para entregar ao cliente), além de uma verificação se a pilha está cheia ou vazia (ato que o entregador faz ao verificar o baú).

Implementando nossa pilha em Java

Primeiramente, vamos criar um array para armazenar nossa pilha. Imaginando o baú, temos uma capacidade de 10 pizzas, por exemplo, já um caminhão, dependendo do tamanho dele e da quantidade de produtos a serem entregues, pode armazenar de 1 a centenas de entregas, e assim por diante. Em nosso caso, primeiro vamos criar o array, depois vamos definir um tamanho de teste para 10 itens em nossa pilha, como mostra a Listagem 1.

public Object[] pilha;
Listagem 1. Declarando o array

Foi utilizado o tipo Object para armazenar textos ou números, uma forma mais genérica, apenas como teste de pilha, como mostra a Listagem 2.

public int posicaoPilha;
Listagem 2. Variável para armazenar a posição atual na pilha

Aqui foi criado uma variável que exibe a posição atual na pilha, se a posição for 10, então chegamos ao topo da pilha e não poderão ser inseridos mais itens.

Agora na Listagem 3 o construtor será definido o tamanho da pilha e inicializado a posição.

public Pilha() { this. posicaoPilha = -1; // indica que esta nula, vazia, pois a posição zero //do array já armazena informação this.pilha = new Object[10]; // criando uma pilha com 10 posições }
Listagem 3. Inicializando a pilha

Agora vamos criar uma função que verifique se a pilha está vazia (isEmpty). Observe a Listagem 4.

public boolean pilhaVazia() { if (this. posicaoPilha == -1) { return true; // Verifica que o atributo posicaoPilha é igual a -1, //se for, a pilha é nula, ou seja, ainda esta vazia, //retornando verdadeiro. } return false; }
Listagem 4. Função para verificar se a pilha está vazia

Agora é necessário verificarmos qual o tamanho da pilha atual, ou seja, o entregador olha quantas pizzas ainda tem dentro do baú para entregar, como mostra a Listagem 5.

public int tamanho() { if (this.pilhaVazia()) { return 0; // aqui indica que não tem nenhum conteúdo dentro da pilha } return this. posicaoPilha + 1; // aqui indica quantos itens tem dentro da pilha, somando-se 1, //pois a pilha inicia no zero. Logo, se tivermos 3 itens na pilha, // o atributo posicaoPilha vai exibir 2. //Para sabermos quantos itens há, precisamos somar um. }
Listagem 5. Função que retorna a quantidade de itens na pilha

Agora é necessário um método para empilhar itens dentro da pilha, ou seja, a forma que o entregador pega a pizza e insere sobre a última pizza que está no baú, como vemos na Listagem 6.

public void empilhar(Object valor) { // push if (this. posicaoPilha < this.pilha.length - 1) { // verifica se a posicaoPilha é menor do que o tamanho da pilha, //se for, então é inserido o valor na pilha e ao mesmo tempo é feito //o incremento do atributo posicaoPilha this.pilha[++posicaoPilha] = valor; } }
Listagem 6. Função para empilhar itens

Depois de criada uma forma de empilhar, temos de desempilhar, ou seja, hora de o entregador retirar a pizza do baú e entregar ao cliente, como mostra a Listagem 7./p>

public Object desempilhar() { //pop if (pilhaVazia()) { return null; // primeiro verificamos se a pilha esta vazia, //se estiver, nada será realizado } return this.pilha[this. posicaoPilha --]; // aqui retorna o que tem na última posição da pilha //e decrementa o atributo posicaoPilha }
Listagem 7. Função para remover itens da lista

Na Listagem 8 vamos ver o resultado da pilha completa em funcionamento.

public class Pilha { public Object[] pilha; public int posicaoPilha; public Pilha() { this.posicaoPilha = -1; // indica que esta nula, vazia, pois posição um indica que contém informação this.pilha = new Object[1000]; // criando uma pilha com 1000 posições } public boolean pilhaVazia() { //isEmpty if (this.posicaoPilha == -1) { return true; } return false; } public int tamanho() { //is if (this.pilhaVazia()) { return 0; } return this.posicaoPilha + 1; } public Object exibeUltimoValor() { //top if (this.pilhaVazia()) { return null; } return this.pilha[this.posicaoPilha]; } public Object desempilhar() { //pop if (pilhaVazia()) { return null; } return this.pilha[this.posicaoPilha--]; } public void empilhar(Object valor) { // push if (this.posicaoPilha < this.pilha.length - 1) { this.pilha[++posicaoPilha] = valor; } } public static void main(String args[]) { Pilha p = new Pilha(); p.empilhar("Portuguesa "); p.empilhar("Frango com catupiry "); p.empilhar("Calabresa "); p.empilhar("Quatro queijos "); p.empilhar(10); while (p.pilhaVazia() == false) { System.out.println(p.desempilhar()); } } }
Listagem 8. Pilha completa em funcionamento

Pronto, a pilha está funcionando. Nosso entregador pode empilhar e desempilhar as pilhas sem maiores problemas.

Conclusão

A pilha é uma estrutura simples de ser implementada. Apesar de algumas limitações, pode ser utilizado para diversos fins, como sistemas de logísticas, por exemplo.

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados