Está en la página 1de 19

Implementación

de Pilas con Listas


Enlazadas

Taller de
Algoritmos y
Estructuras
de Datos I

1
Implementación de Pilas con
Listas Enlazadas

Las características propias de la Pila nos permite utilizarlas en varias


aplicaciones facilitándonos:

 Los compiladores comprueban la sintaxis de los programas.


Ejemplo: si falta el cierre de un comentario */ entonces se lanzan
errores. El compilador debe comprobar que los distintos símbolos
están equilibrados. [()] es correcto. [(]) es incorrecto

 Controlar, desde el Sistema Operativo, la ejecución de todas las


ordenes de un archivo batch

 Recordar al programa principal el punto de llamada de un


subprograma y retornar al mismo cuando este termine.

 Formar cadenas de caracteres

 Separar texto

 Evaluar expresiones matemáticas

 Deshacer la última operación realizada, por ejemplo en un


procesador de texto u otros programas similares.

Ahora bien, sobre la PILA podemos realizar las operaciones de:

- PUSH: poner o meter

- POP: sacar

Las pilas pueden ser representadas por medio de una lista unidireccional o
por un array lineal.

Representaremos las pilas por medio de un array lineal

Tendremos un puntero especial apuntando a la CIMA y una variable


MAXPILA que determina el tamaño máximo de la pila.

Para controlar el OVER-UNDERFLOW hay que saber determinar el tamaño


de la pila; porque si lo hacemos demasiado grande no habrá OVERFLOW
pero tendremos una pérdida importante de memoria y viceversa.
Operaciones para manipular una Pila

Las operaciones que debemos implementar en una estructura de datos de tipo


pila son las siguientes:

 Creación: crea una pila vacía

 Inserción: agrega un nuevo elemento en el cima

 apilar(x)

 Borrado: elimina el elemento de la cima, si la pila no esta vacía

 x = desapilar()

 Consulta:

 Pila Vacía

 Elemento en la cima

Básicamente existen 2 técnicas posibles para lograr implementar estas


funciones en tiempo constante:

 Pilas implementadas con datos de forma contigua a través de un


Array o Vector

 Pilas implementadas con datos de forma no contigua a través de una


estructura de datos de tipo Lista Enlazada Simple

Interfaz Pila

La interfaz pila tiene los siguientes métodos que deberán ser


implementados tanto en la pila vector como en la pila lista enlazada

public interface Pila{

public int tamanyo();

public boolean esVacia();

public void apilar( Object o );

public Object desapilar()

throws DesbordamientoInferior;

public Object cima()

throws DesbordamientoInferior;

Implementación de la Pila con un Vector

La primera implementación de la pila que veremos es utilizando un vector y


un entero. El entero es la cima de la pila (cdp) y es el índice del
vector
correspondiente al elemento situado en la cima de la pila. Así cuando cdp es
igual a -1, la pila esta vacía.
Para apilar se incremente cdp y se inserta el nuevo elemento en la posición
cdp del vector.

El acceso a la cima de la pila resulta trivial y la operación de desapilar se


realiza decrementando cdp.

public class PilaVector implements Pila {

private static final int N=1000;

private int capacidad;

private Object[] S;

private int cima=-1;

public PilaVector(){ this(N); }

public PilaVector( int cap ){

capacidad = cap;

S = new Object[capacidad];

public int tamanyo() { return cima + 1; }

public boolean esVacia() { return cima < 0; }

public Object cima()throws DesbordamientoInferior {

if( esVacia() )

throw new DesbordamientoInferior(“Pila vacía”);

return S[ cima ];

Implementación de la Pila con una Lista Enlazada

Una alternativa a la implementación contigua, empleando vectores, consiste


en utilizar una lista enlazada. La cima de la pila está representada por el
primer elemento de la lista. Para implementar la operación apilar, creamos
un nuevo
nodo y lo incluimos en la lista como primer elemento. La pila se representa
por un único atributo cimaDePila es una referencia que apunta la primer
Nodo de la lista enlazada. El constructor de la clase PilaLista crea una lista
vacía inicializando cimaDePila a null.
La operación apilar requiere una única línea de código: la creación de un
nuevo nodo NodoLista. El atributo contiene el elemento x a insertar y el
elemento siguiente para el nuevo nodo de la cima de pila inicial. El nuevo
nodo creado para a ser la nueva cima.

La operación desapilar también es sencilla, tras el test para detectar la


pila vacía se actualiza cimaDePila de modo que apunte al segundo
elemento de la lista.

Clase Nodo

class Nodo{

Object dato;

Nodo siguiente;

//constructor

public Nodo( Object o, Nodo n ){

dato = o;

siguiente = n;

Clase PilaEnlazada

public class PilaEnlazada implements Pila{

private Nodo cima;

private int tamanyo;

public PilaEnlazada(){

cima = null;

tamanyo = 0;

public int tamanyo(){ return tamanyo; }


public boolean esVacia(){

return ( cima==null );

public int apilar( Object o ){

Nodo n = new Nodo(o, cima);

cima = n;

tamanyo++;

public Object cima() throws DesbordamientoInferior{

if( esVacia() )

throw new DesbordamientoInferior(“Pila Vacía”);

return cima.dato;

public Object desapilar() throws DesbordamientoInferior

if (esVacia())

throw new DesbordamientoInferior(“Pila vacía”);

Object temp = cima.dato;

cima = cima.siguiente;

tamanyo--;

return temp;

Caso Práctico

Supongamos la siguiente situación, Ud. esta desarrollando un sistema para


una institución educativa, y necesita almacenar en una estructura de datos
líneas tipo Pila los alumnos, la implementación la realizaremos a través de
una lista enlazada simple. Las clases intervinientes son Personas, Alumnos y
Materia. Alumno extiende de Persona, y Alumno puede cursar una o varias
Materias. Desde una clase Test que contienen el método main utilizaremos
una estructura de tipo Pila implementada con lista enlazada para almacenar
los alumnos:
Clase Persona

package uesiglo21.taller1.model;

public abstract class Persona {

private int dni;

private String nomb;

private String apel;

// Constructor de la clase Persona

public Persona (int dni,String nomb,String apel){

this.dni = dni;

this.nomb = nomb;

this.apel = apel;

// Métodos getter y setter

public int getDni() {

return dni;

public void setDni(int dni) {

this.dni = dni;

public String getNomb() {

return nomb;

public void setNomb(String nomb) {

this.nomb = nomb;

public String getApel() {


return apel;

public void setApel(String apel) {

this.apel = apel;

public String toString(){

String aux;

aux="D.N.I: " + dni + "\nNombre: " + nomb + "\nApellido: " + apel;

return aux;

Clase Alumno

package uesiglo21.taller1.model;

public class Alumno extends Persona{

private String legajo;

// Se utiliza un array de java de 15 elementos de máximo

private Materia Mat[]= new Materia[15];

// Constructor de la clase alumno

public Alumno (int dni,String nomb,String apel,String legajo){

super(dni,nomb,apel);

this.legajo=legajo;

// Inicializa las materias en null

for (int i = 0; i < Mat.length ; i++) {

Mat[i]= null;

}
public String getLegajo() {

return legajo;

public void setLegajo(String legajo) {

this.legajo = legajo;

public Materia[] getMat() {

return Mat;

public void setMat(Materia[] mat) {

Mat = mat;

// Asigna una materia al alumno y la guarda en el array

public boolean cargarAlumno(Materia m){

for (int i = 0; i < Mat.length ; i++) {

if (Mat[i] == null) {

Mat[i]=m;

return true;

return false;

public String toString(){

String aux;

aux=super.toString();
aux+="\nLegajo: " + legajo;
aux+="\nMaterias: ";

for (int i = 0; i < Mat.length ; i++) {

aux+= "\n" + Mat[i] ;

return aux;

Clase Materia

package uesiglo21.taller1.model;

public class Materia {

private String denom;

private int semestre;

// Constructor de la clase materia

public Materia (String demon,int semestre){

this.denom = demon;

this.semestre = semestre;

public String getDenom() {

return denom;

public void setDenom(String denom) {

this.denom = denom;

public int getSemestre() {

return semestre;

public void setSemestre(int semestre) {

this.semestre = semestre;
}

public String toString(){

String aux;

aux="Denominacion: " + denom + " - Semestre: " + semestre;

return aux;

Interfaz Pila

package uesiglo21.taller1.model;

public interface Pila {

public int tamanio();

public boolean esVacia();

public void apilar(Object o);

public void desapilar() throws DesbordamientoInferior;

public Object cima()throws DesbordamientoInferior;

public Object cimaYDesapilar()throws DesbordamientoInferior;

Clase NodoPila

package uesiglo21.taller1.model;

public class NodoPila {

private Object dato;

NodoPila siguiente;
// El constructor del nodo recibo el dato a guardar y el nodo siguientes
public NodoPila(Object O, NodoPila siguiente){

this.dato=O;

this.siguiente=siguiente;

public NodoPila getSiguiente() {

return siguiente;

public void setSiguiente(NodoPila siguiente) {

this.siguiente = siguiente;

public Object getDato() {

return dato;

public void setDato(Object dato) {

this.dato = dato;

Clase PilaLista

package uesiglo21.taller1.model;

public class PilaLista implements IPila {

private NodoPila cima;


private int tamanio;

// Constructor sin parametros

public PilaLista(){

cima=null;

tamanio=0;

public int tamanio() {

return tamanio;

public boolean esVacia() {

if(cima==null){

return true;

}else{

return false;

// inserta un objeto en la pila

public void apilar(Object o) {

// apila el Nuevo nodo

cima=new NodoPila(o,cima);

tamanio++;

// Elimina el ultimo elemento ingresado

public void desapilar() throws DesbordamientoInferior{


if (esVacia()){
throw new DesbordamientoInferior("CIMA");

cima=cima.getSiguiente();

tamanio--;

// devuelve la cima (el elemento mas reciente)

public Object cima()throws DesbordamientoInferior{

if (esVacia()){

throw new DesbordamientoInferior("CIMA");

return cima.getDato();

// método que desaplila y devuelve la nueva cima

public Object cimaYDesapilar() throws DesbordamientoInferior{

if (esVacia()){

throw new DesbordamientoInferior("CIMA");

cima=cima.getSiguiente();

tamanio--;

if (esVacia()){

throw new DesbordamientoInferior("CIMA");

return cima.getDato();

}
}

Clase Test

Esta clase la utilizamos para probar el funcionamiento del código anterior.

package uesiglo21.taller1.view;

import uesiglo21.taller1.model.*;

public class Test {

public static void main(String[] args) throws DesbordamientoInferior


{

try {

// Creamos 3 Materias

Materia m1 = new Materia("ADE",1);

Materia m2 = new Materia("ACO",2);

Materia m3 = new Materia ("SOR",3);

// Creamos 4Alumnos

Alumno a1 = new Alumno(31549674,"Jose","Gomez","SOF-


000090");

Alumno a2 = new Alumno(31549675,"Pablo","Ramirez","SOF-


000091");

Alumno a3 = new Alumno(31549676,"Mauro","Lopez","SOF-


000093");

Alumno a4 = new
Alumno(31549677,"Pedro","Gonzalez","SOF-000094");

// Asociamos los alumnos a las manterias


a1.cargarAlumno(m1);

a1.cargarAlumno(m2);

a1.cargarAlumno(m3);

a2.cargarAlumno(m1);

a2.cargarAlumno(m2);

a2.cargarAlumno(m3);

a3.cargarAlumno(m1);

a3.cargarAlumno(m2);

a3.cargarAlumno(m3);

a4.cargarAlumno(m1);

a4.cargarAlumno(m2);

a4.cargarAlumno(m3);

// creamos una pila de tipo lista vacia (Sin elementos)

PilaLista pl = new PilaLista();

// Apilamos los4 alumnos Anteriores

System.out.println("--------Apilar---------");

pl.apilar(a1);

System.out.println("----");

System.out.println(pl.cima().toString());

pl.apilar(a2);

System.out.println("----");

System.out.println(pl.cima().toString());

pl.apilar(a3);

System.out.println("----");
System.out.println(pl.cima().toString());
pl.apilar(a4);

System.out.println("----");

System.out.println(pl.cima().toString());

System.out.println("-----Cima-----");

System.out.println(pl.cima().toString());

//Desapilamos el ultimo element

System.out.println("\n---------Desapilar--------");

pl.desapilar();

System.out.println("---Nueva Cima----");

System.out.println(pl.cima().toString());

// Desapilamos y hacemos cima

System.out.println("\n---------Desapilar y Cima---------");

System.out.println("---Nueva Cima----");

System.out.println(pl.cimaYDesapilar().toString());

// Probamos el desbordamiento cuando la pila se queda sin elementos

System.out.println("\n-----Desbordamiento-----");

pl.desapilar();

pl.desapilar();

pl.desapilar();

} catch (Exception e) {
System.out.println("Se ha producido un error al manipular la
Pila");

}
Referencia Bibliográfica
Mark Allen Weiss, “Estructuras de Datos en Java”, ed. Addison Wesley. (2000)

Bibliografía Ampliatoria

En el caso que quieras ampliar los conceptos que hemos visto te


recomiendo la siguiente bibliografía

 Fundamentos de algoritmo y programación , autor Lage Fernando


 Introducción a la programación, autor Ramirez Felipe
 Algoritmo y Programación, autor Perez Berro
 Introducción al diseño y análisis de algoritmos, autor Leer R.C.T.
 Metodología de la Programación, autor Cairo B.
 C. Algoritmos, programación y estructuras de datos, autor Joyanes
Aguilar
 Matemática Discreta y Algoritmos, autor Perez Julio
 Algoritmo y estructura de datos una perspectiva en C, autor
Joyanes Aguilar
 Algoritmos datos y programas, autor De Giusti
 Algoritmos fundamentales, autor Knuth Donald
 Estructuras de datos y algoritmos, autor Hernandez Roberto
 Introducción al análisis de algoritmos, autor Sanchez Velásquez
 Diseño y análisis de algoritmos, autor Torres Carmen

También podría gustarte