Pila (Stack) en Java desde cero - Estructura de Datos en JAVA

 Pila en Java - Estructura de Datos ☕

pilas en java estructura de datos

 🚀¿Quieres aprender a crear una pila o Stack en Java? En este artículo te explicaremos todo lo que necesitas saber para que puedas empezar a utilizar este importante tipo de estructura de datos. Desde su definición y funcionamiento, hasta cómo implementarla en tu código. ¡Sigue leyendo para descubrir cómo puedes mejorar tus habilidades de programación!

REPOSITORIO EN GITHUB - ESTRUCTURA DE DATOS

¿Qué es una pila en Java?

🤔 Antes de aprender a crear una pila en Java, es importante que entiendas su definición y su funcionamiento. En esencia, una pila es una estructura de datos lineal que se utiliza para almacenar y organizar elementos. Esta estructura se caracteriza por tener dos operaciones principales: push (apilar) y pop (desapilar).

Cómo crear una pila en Java

Para la creación desde cero de una Pila en Java, primero tenemos que saber que una pila en Java funciona siguiendo el principio de LIFO (Last In, First Out). Esto significa que el último elemento que se apila en la pila es el primero en ser desapilado. Por ejemplo, si se apilan los elementos "A", "B" y "C", el elemento "C" será el primero en ser desapilado. Teniendo en cuenta lo anterior vamos a empezar las Clases necesarias.


Clase Nodo

La clase Nodo es la que nos va a crear los enlaces entre los Nodos de la Pila, por ello es que cuenta con dos atributos, Object dato y Nodo siguiente, el Object dato significa el dato que se va a estar almacenando en nuestra pila, y el Nodo siguiente significa el nodo que está después.
package Pilas;

public class Nodo {
    private Object dato;
    private Nodo siguiente;

    public Nodo(Object dato, Nodo siguiente) {
        this.dato = dato;
        this.siguiente = siguiente;
    }

    public Object getDato() {
        return dato;
    }

    public void setDato(Object dato) {
        this.dato = dato;
    }

    public Nodo getSiguiente() {
        return siguiente;
    }

    public void setSiguiente(Nodo siguiente) {
        this.siguiente = siguiente;
    }

    @Override
    public String toString() {
        return "Nodo{" + "dato=" + dato + ", siguiente=" + siguiente + '}';
    }


}

Ahora vamos a crear la clase Pila, la cual va a tener todas las acciones o funciones de ella respectivamente, entre las cuales apilar(), desapilar(), imprimir(), también encontraremos algunos ejercicios resueltos, los cuales van a poder encontrar en el repositorio de GitHub.

package Pilas;

public class Pila {
    private Nodo cima;
    private int tam;

    public Pila() {
        this.cima = null;
        this.tam = 0;
    }

    public boolean vacia() {
        //si la cima esta en null es porque esta vacia
        return cima == null;
    }

    //agregar en la cima
    public void apilar(Object dato) {
        Nodo nuevo = new Nodo(dato, cima);
        cima = nuevo;
        tam++;
    }

    //eliminar cima
    public void desapilar() {
        if (!vacia()) {
            cima = cima.getSiguiente();
            tam--;
        }
    }

    public void ejercicio1(int x) {
        if (!vacia()) {
            Pila aux = new Pila();

            while (!vacia()) {
                aux.apilar(cima.getDato());
                desapilar();
            }

            while (!aux.vacia()) {
                for (int i = 0; i < x; i++) {
                    apilar(aux.getCima().getDato());
                }
                aux.desapilar();
            }

        }
    }

    public void ejercicio2() {
        if (!vacia()) {
            Pila aux = new Pila();

            int menor = (int) (cima.getDato());

            //para vaciar la pila
            while (!vacia()) {

                if ((int) (cima.getDato()) < menor) {
                    menor = (int) (cima.getDato());
                }
                aux.apilar(cima.getDato());
                desapilar();
            }

            apilar(menor); // se ubica el menor

            while (!aux.vacia()) {
                if (!aux.getCima().getDato().equals(menor)) {
                    apilar(aux.getCima().getDato());
                }
                aux.desapilar();

            }
        }
    }

    public void ejercicio3(Object dato) {
        if (!vacia()) {
            boolean flag = false;
            Pila aux = new Pila();
            while (!vacia()) {
                if (cima.getDato().equals(dato)) {
                    flag = true;
                }
                aux.apilar(cima.getDato());
                desapilar();
            }

            if (!flag) {

                while (!aux.vacia()) {
                    apilar(aux.getCima().getDato());
                    aux.desapilar();
                }
                apilar(dato);
            } else {
                while (!aux.vacia()) {
                    if (!aux.getCima().getDato().equals(dato)) {
                        apilar(aux.getCima().getDato());
                    }
                    aux.desapilar();
                }
                apilar(dato);
            }
        }
    }

    public boolean recorrerOtraPila(Pila pila, Object dato) {
        boolean salida = false;
        if (!pila.vacia()) {
            Nodo nodo = pila.getCima();
            while (pila.cima != null) {
                if (dato == pila.cima.getDato()) {
                    salida = true;
                }
                pila.cima = pila.cima.getSiguiente();
            }
            pila.cima = nodo;
        }
        return salida;
    }

    public void ejercicio4(Pila pila1, Pila pila2) {
        if (!vacia()) {
            Pila aux = new Pila();
            while (!pila1.vacia()) {
                if (recorrerOtraPila(pila2, pila1.getCima().getDato())) {
                    pila1.desapilar();
                } else {
                    aux.apilar(pila1.getCima().getDato());
                    pila1.desapilar();
                }
            }
            while (aux.getCima() != null) {
                apilar(aux.getCima().getDato());
                aux.desapilar();
            }
        }
    }

    public void eliminar(Object dato) {
        if (!vacia()) {
            Nodo aux = cima;
            int tamAux = tam;
            Pila pilaAux = new Pila();
            while (cima != null && cima.getDato() != dato) {
                pilaAux.apilar(cima.getDato());
                desapilar();
            }
            if (cima == null && tamAux == pilaAux.getTam()) {
                //esta condicion es en caso de que no se encuentre
                // el elemento a eliminar
                cima = aux;
            } else {
                //en caso de que si esté el elemento a eliminar
                desapilar();
                while (pilaAux.getCima() != null) {
                    apilar(pilaAux.getCima().getDato());
                    pilaAux.desapilar();
                }
            }
        }
    }

    //mostrar normal
    public String mostrar() {
        String salida = "";
        Nodo aux = cima;
        while (aux != null) {
            salida += aux.getDato() + " ";
            aux = aux.getSiguiente();
        }
        return salida;
    }

    //mostrar segun teoria
    //recorriendo todo usando la cima
    public String mostrarP() {
        String salida = "";
        Nodo aux = cima;
        while (cima != null) {
            salida += cima.getDato() + " ";
            cima = cima.getSiguiente();
        }
        cima = aux;
        //se recupera el valor de la cima
        return salida;
    }

    //Getter and Setter
    public Nodo getCima() {
        return cima;
    }

    public void setCima(Nodo cima) {
        this.cima = cima;
    }

    public int getTam() {
        return tam;
    }

    public void setTam(int tam) {
        this.tam = tam;
    }

    @Override
    public String toString() {
        return "Pila{" + "cima=" + cima + ", tam=" + tam + '}';
    }

}

Si detallamos cuidadosamente el código de la clase Pila, vamos a ver dos métodos de mostrar, "mostrar() y mostrarP()", en cuestion de funcionamiento realizan lo mismo, pero mostrar() lo hace con un Nodo auxiliar mientras que recorre toda la pila, mostarP() lo hace según la teoría hace todo el recorrido usando la cima, al finalizar el ciclo while se recupera los enlaces con un nodo auxiliar que contiene dichos enlaces.


Clase Main

En esta clase vamos a usar la pila que hemos creado anteriormente, aquí vamos a usar los métodos que vienen en esta Pila.


package Pilas;

public class Main {
    public static void main(String[] args) {
        Pila pila = new Pila();
        pila.apilar(8);
        pila.apilar(5);
        pila.apilar(2);
        pila.apilar(4);
        pila.apilar(6);

        System.out.println(pila.mostrar());
        pila.eliminar(6);
        System.out.println(pila.mostrar());
    }
}

Si quieres ver la solución de cada uno de los ejercicios que tiene esta clase Pila, lo puedes ver desde nuestro canal de YouTube dando click aquí.


Crear una pila en Java desde cero es un ejercicio muy útil para aprender los fundamentos de la estructura de datos de la pila y su implementación en Java. En este artículo, hemos cubierto los conceptos básicos de la pila, por qué es útil y cómo puedes implementarla en Java. ¡Espero que hayas aprendido algo nuevo y útil!

Artículo Anterior Artículo Siguiente

Formulario de contacto