Implementación de una pila en java con un array

Paso 1: modelizar la pila mediante un array

Para poder realizar una implementación de una pila en java con un array, primero de todo, debemos diseñar cómo queremos hacerlo. En esta implementación lo que se hace es tener una variable ‘size’ que nos indicará cuántos elementos tiene el array y, además, nos señalará en que posición introduciremos (next pos = size) o eliminaremos (top = size – 1) el siguiente elemento. Deberemos tener en cuenta también que el array puede llenarse. En ese caso, lo redimensionaremos doblando su capacidad.

diagrama de la implementación de una pila en java con un array

Paso 2: crear la interfície Stack<E>

En esta interfície pondremos los métodos principales que debe tener una pila.

public interface Stack<E> {

    /**
     * Añade un elemento a la pila
     *
     * @param element
     */
    void push(E element);

    /**
     * Elimina el elemento del top de la pila
     *
     * @return elemento del top de la pila
     * @throws java.util.NoSuchElementException si la pila esta vacia
     */
    E pop();

    /**
     * Permite consultar el elemento del top de la pila
     *
     * @return elemento del top de la pila
     * @throws java.util.NoSuchElementException si la pila esta vacia
     */
    E peek();

    /**
     * Permite consultar cuantos elementos tiene la pila
     *
     * @return numero de elementos en la pila
     */
    int size();
}

Paso 3: implementar los métodos de la pila

Aquí tienes cómo se ha desarrollado la implementación de una pila en java con un array.

import java.util.NoSuchElementException;

public class ArrayStack<E> implements Stack<E> {

    private Object[] array;
    private int size;

    public ArrayStack() {
        array = new Object[10];
        size = 0;
    }

    @Override
    public void push(E element) {
        if (size == array.length) {
            resizeArray();
        }
        array[size] = element;
        size += 1;
    }

    private void resizeArray() {
        var newArray = new Object[2 * array.length];

        for (int i = 0; i < array.length; i++) {
            newArray[i] = array[i];
        }

        array = newArray;
    }

    @Override
    public E pop() {
        if (size == 0)
            throw new NoSuchElementException("Pop on empty Stack");

        var top = array[size - 1];
        array[size - 1] = null;
        size -= 1;
        return (E) top;
    }

    @Override
    public E peek() {
        if (size == 0)
            throw new NoSuchElementException("Peek on empty Stack");

        var top = array[size - 1];
        return (E) top;
    }

    @Override
    public int size() {
        return size;
    }
}

Veamos un poco cómo se ha programado todo. En primer lugar, se han creado dos variables de instancia privadas: un arreglo de objetos y el entero size. Estas dos variables son las que modelizan nuestra implementación de la pila mediante un array.

El siguiente paso será definir el constructor de pilas. Se ha optado por inicializar el array con un máximo de 10 posiciones aunque, si se necesitase más adelante, podría ser redimensionado. La variable size ha sido inicializada a 0 ya que en un principio la pila no tiene elementos.

Ahora, entremos un poco más en detalle en cada método:

  • void push(E element): en este método solo debíamos comprobar que el array no esté lleno y añadir el elemento en la posición size del array. En el caso de que esté lleno, es decir, que haya tantos elementos como espacios tiene el array (size == array.length), lo redimensionaremos. Para ello se ha creado una función privada auxiliar resizeArray() que crea un nuevo vector con el doble de capacidad al que se le copian los valores que tenía el antiguo. Finalmente, la variable de instancia array pasa a apuntar a este nuevo arreglo con espacios libres.
  • E pop(): esta función debe comprobar que no se esté intentando eliminar un elemento de una pila vacía. En ese caso, lanzará una NoSuchElementException. Si no, se establecerá la posición top (size – 1) como null y se retornará el elemento borrado.
  • E peek(): esta función debe comprobar que no se esté intentando consultar el elemento top de una pila vacía. En ese caso, lanzará una NoSuchElementException. Si no, devolverá el elemento del top.
  • int size(): como este método debe devolver el número de elementos en la pila, que lo tenemos guardado en la variable de instancia size, solo debemos devolver el valor de esta variable entera.

COMPLEJIDAD: El coste de añadir un elemento en la pila si redimensionamos doblando la capacidad es O(1) o constante. En cambio, eliminar o consultar un elemento en una pila tiene un coste lineal o O(n) ya que, en el peor de los casos, el elemento puede ser el del fondo de la pila.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Estoy de acuerdo con que el responsable de la web Aprendiz de Programación use los datos proporcionados en este comentario para poder comunicarse de forma efectiva.

Scroll al inicio