Estrutura de Dados: Implementação de Pilhas em Java

Uma pilha é uma estrutura de dados linear que segue o princípio "Last In, First Out" (LIFO), ou seja, o último elemento inserido é o primeiro a ser removido. As operações em pilhas são restritas ao topo, sendo impossível acessar ou remover elementos do meio ou base diretamente.

As operações fundamentais de uma pilha incluem:

  • push - Insere um novo elemento no topo da pilha
  • peek - Retorna o elemento do topo sem removê-lo
  • pop - Remove e retorna o elemento do topo

Uma pilha pode ser implementada utilizando tanto arrays quanto listas encadeadas. A implementação com arrays oferece acesso mais rápido aos elementos, mas possui tamanho fixo. Já a implementação com listas encadeadas permite crescimento dinâmico, mas tem maior sobrecarga de memória.

Implementação com Array

A seguir, uma implementação de pilha utilizando uma estrutura de array:

public class Pilha {
    private Object[] elementos;
    private int capacidade;
    private int topo;
    
    public Pilha(int capacidade) {
        this.capacidade = capacidade;
        this.elementos = new Object[capacidade];
        this.topo = -1;
    }
    
    public void empilhar(Object item) {
        if (estaCheia()) {
            throw new IllegalStateException("A pilha está cheia");
        }
        elementos[++topo] = item;
    }
    
    public Object desempilhar() {
        if (estaVazia()) {
            throw new IllegalStateException("A pilha está vazia");
        }
        return elementos[topo--];
    }
    
    public Object topo() {
        if (estaVazia()) {
            throw new IllegalStateException("A pilha está vazia");
        }
        return elementos[topo];
    }
    
    public boolean estaVazia() {
        return topo == -1;
    }
    
    public boolean estaCheia() {
        return topo == capacidade - 1;
    }
    
    public int tamanho() {
        return topo + 1;
    }
}

Testando a Implementação com Array

public static void main(String[] args) {
    Pilha pilha = new Pilha(5);
    
    pilha.empilhar("Primeiro");
    pilha.empilhar("Segundo");
    pilha.empilhar("Terceiro");
    pilha.empilhar(100);
    
    System.out.println("Tamanho atual da pilha: " + pilha.tamanho());
    
    Object elementoTopo = pilha.topo();
    System.out.println("Elemento no topo: " + elementoTopo);
    
    pilha.desempilhar();
    System.out.println("Elemento removido do topo");
    
    System.out.println("Novo tamanho da pilha: " + pilha.tamanho());
}

Resultado esperado:

Tamanho atual da pilha: 4
Elemento no topo: 100
Elemento removido do topo
Novo tamanho da pilha: 3

Implementação com Lista Encadeada

Agora, uma alternativa de implementação utilizando lista encadeada simples:

public class PilhaEncadeada {
    private No cabeca;
    private int tamanho;
    
    private static class No {
        Object dado;
        No proximo;
        
        No(Object dado) {
            this.dado = dado;
            this.proximo = null;
        }
    }
    
    public PilhaEncadeada() {
        this.cabeca = null;
        this.tamanho = 0;
    }
    
    public void empilhar(Object item) {
        No novoNo = new No(item);
        novoNo.proximo = cabeca;
        cabeca = novoNo;
        tamanho++;
    }
    
    public Object desempilhar() {
        if (estaVazia()) {
            throw new IllegalStateException("A pilha está vazia");
        }
        Object dado = cabeca.dado;
        cabeca = cabeca.proximo;
        tamanho--;
        return dado;
    }
    
    public Object topo() {
        if (estaVazia()) {
            throw new IllegalStateException("A pilha está vazia");
        }
        return cabeca.dado;
    }
    
    public boolean estaVazia() {
        return cabeca == null;
    }
    
    public int tamanho() {
        return tamanho;
    }
}

Tesatndo a Implementação com Lista Encadeada

public static void main(String[] args) {
    PilhaEncadeada pilha = new PilhaEncadeada();
    
    pilha.empilhar(10);
    pilha.empilhar(20);
    pilha.empilhar(30);
    pilha.empilhar(40);
    
    System.out.println("Tamanho atual: " + pilha.tamanho());
    
    Object elementoTopo = pilha.topo();
    System.out.println("Elemento no topo: " + elementoTopo);
    
    pilha.desempilhar();
    System.out.println("Elemento removido");
    
    System.out.println("Novo tamanho: " + pilha.tamanho());
}

Resultado esperado:

Tamanho atual: 4
Elemento no topo: 40
Elemento removido
Novo tamanho: 3

Tags: estrutura-de-dados pilhas java Algoritmos LIFO

Publicado em 8-20 07:58