Computing">
Nothing Special   »   [go: up one dir, main page]

Pilas

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 11

Introducción:

Las estructuras de datos desempeñan un papel fundamental en la ciencia de la


computación y la programación, ya que proporcionan un marco para organizar y
administrar datos de manera eficiente. Entre las diversas estructuras de datos utilizadas
en informática, las pilas ocupan una posición destacada debido a su simplicidad y
versatilidad en una amplia variedad de aplicaciones.

Concepto de Pila:
El término "pila" hace referencia a una estructura organizada de elementos que solo
pueden ser accedidos desde un punto único o extremo, conocido como la parte superior o
cima. En una pila, los elementos se añaden o eliminan exclusivamente desde la parte
superior, siguiendo un patrón similar al apilamiento de platos o libros.

Para una comprensión más profunda, podemos definir una pila como una colección de
datos en la que los elementos se organizan de manera que solo se pueden introducir o
eliminar desde un punto específico llamado "cima". La organización de la pila asegura que
el elemento en la cima sea el primero en ser accesible, seguido por el elemento justo
debajo de él y así sucesivamente. No es necesario que los elementos de la pila sean
comparables mediante el operador "menor que" (<) y pueden pertenecer a cualquier tipo
de dato.

Es importante destacar que los elementos en la pila deben retirarse en el orden contrario
al que fueron agregados originalmente. Por ejemplo, al crear una pila de libros, si primero
colocamos un diccionario, luego una enciclopedia encima de él y finalmente una novela
encima de ambos, la novela será el elemento en la parte superior de la pila y deberá
retirarse en primer lugar.

Al retirar los libros de la pila, es importante seguir un orden específico: primero se quita la
novela, luego la enciclopedia y, finalmente, el diccionario. Esto se debe a una propiedad
particular de las pilas, donde el último elemento agregado es el primero en ser retirado.
Esta característica distingue a las pilas como estructuras de datos LIFO (Last-In, First-
Out).

Las operaciones típicas realizadas en una pila son el "Insertar" (también conocido como
"push"), que agrega un elemento en la parte superior de la pila, y el "Quitar" (o "pop"), que
elimina o extrae un elemento de la pila.
Las características principales de una pila son las siguientes:

Estructura LIFO: Una pila sigue el principio "Last-In, First-Out", lo que significa que el
último elemento en ser insertado (apilado) es el primero en ser retirado (desapilado).

Acceso Limitado: Los elementos de una pila solo pueden ser accedidos desde un único
punto, que se conoce como la cima (top) de la pila. No se pueden acceder elementos en
medio de la pila directamente.

Operaciones Básicas: Las operaciones básicas en una pila son "Insertar" (push) y "Quitar"
(pop). "Push" agrega un elemento en la cima de la pila, mientras que "pop" elimina o saca
el elemento superior de la pila.

Colección Ordenada: Los elementos en una pila se organizan de manera ordenada,


donde el elemento más reciente (el último en entrar) se encuentra en la parte superior de
la pila, y el elemento más antiguo (el primero en entrar) está en la parte inferior.
No se pueden acceder elementos intermedios: No es posible acceder a elementos en
medio de la pila sin primero retirar los elementos superiores que los cubren. Esto se debe
a la limitación de acceso único desde la cima.

Flexibilidad de tipo de datos: Las pilas pueden contener elementos de diferentes tipos de
datos, no están restringidas a un tipo específico.

Uso común: Las pilas se utilizan en una variedad de aplicaciones, incluyendo la


administración de llamadas de funciones en programas, seguimiento de navegación en un
navegador web, y en algoritmos para revertir o deshacer operaciones.

Estructura de datos eficiente: Las pilas son estructuras de datos eficientes para el manejo
de ciertas tareas, como la reversión de datos o el seguimiento de la historia de acciones
realizadas.

Operaciones para una PILA:


 Push (Empujar): Esta operación se utiliza para agregar un elemento a la parte
superior de la pila. El nuevo elemento se coloca en la parte superior y se convierte
en el elemento actualmente en la cima de la pila.

 Pop (Desapilar): La operación de pop se utiliza para eliminar el elemento en la


parte superior de la pila. Esto significa que el elemento más reciente agregado con
"push" es el primero en ser eliminado con "pop". Después de la operación pop, la
pila queda con un elemento menos.

 Peek (Vistazo o Consulta): Esta operación permite ver el elemento en la parte


superior de la pila sin eliminarlo. Es útil para obtener información sobre el
elemento superior sin modificar la pila.

 Empty (Vaciar o Verificar si está vacía): Se utiliza para verificar si la pila está
vacía o no. Devuelve un valor booleano que indica si la pila no contiene ningún
elemento.
 Size (Tamaño): Esta operación devuelve la cantidad de elementos que hay en la
pila en un momento dado. Ayuda a determinar cuántos elementos están
almacenados en la pila.

APLICACIONES DE PILAS

 Evaluación de expresiones aritméticas: Las pilas se utilizan para evaluar


expresiones aritméticas en notación infija, como (3 + 4) * 5. Las expresiones se
convierten primero en notación posfija (postfix) utilizando una pila y luego se
evalúan utilizando otra pila.

 Implementación de llamadas a funciones: En la mayoría de los lenguajes de


programación, las llamadas a funciones y las devoluciones de llamadas se
gestionan mediante una pila de llamadas (call stack). Cada vez que se llama a una
función, se apila un nuevo marco de pila, y cuando la función termina, se elimina
ese marco de pila.

 Historial de navegación en un navegador web: Los botones "Atrás" y "Adelante" en


un navegador web suelen implementarse utilizando una pila. Cada página web
visitada se agrega a la pila cuando se abre, y al hacer clic en "Atrás" se elimina la
página actual de la parte superior de la pila y se muestra la página anterior.

 Validación de paréntesis y etiquetas HTML: Las pilas se utilizan para verificar si los
paréntesis, corchetes y etiquetas HTML están balanceados y bien formados en un
texto. Cada vez que se encuentra un paréntesis de apertura o una etiqueta de
apertura, se agrega a la pila, y cuando se encuentra un paréntesis de cierre o una
etiqueta de cierre, se compara con el elemento superior de la pila para garantizar
que coincidan.

 Implementación de algoritmos recursivos: A menudo, los algoritmos recursivos se


pueden implementar de manera iterativa utilizando una pila en lugar de una
llamada recursiva real para evitar el desbordamiento de la pila de llamadas (stack
overflow).

 Seguimiento de estados en algoritmos y juegos: En juegos y algoritmos donde se


necesita llevar un registro de múltiples estados o movimientos, una pila puede
usarse para almacenar y recuperar estados anteriores.

 Reversión de cadenas: Una pila puede utilizarse para invertir una cadena de
caracteres. Se puede empujar cada carácter en la pila y luego pop para obtener
los caracteres en orden inverso.

 Implementación de undo/redo en aplicaciones: Las pilas se utilizan para realizar un


seguimiento de las acciones realizadas en una aplicación y permitir al usuario
deshacer y rehacer estas acciones.

ALGORITMOS PARA EL MANEJO DE PILAS

PILA CON MEMORIA DINÁMICA


package com.mycompany.practica;
public class Practica {
public class PilaEnMemoriaDinamica<T> {
private class Nodo {
T elemento;
Nodo siguiente;

Nodo(T elemento) {
this.elemento = elemento;
}
}

private Nodo cima; // El nodo superior de la pila


private int tamaño; // El tamaño actual de la pila
public PilaEnMemoriaDinamica() {
cima = null; // Inicialmente, la pila está vacía
tamaño = 0; // El tamaño es cero
}

// Método para agregar un elemento a la pila (push)


public void push(T elemento) {

Nodo nuevoNodo = new Nodo(elemento); // Crear un nuevo nodo con el elemento

nuevoNodo.siguiente = cima; // Establecer el siguiente del nuevo nodo como el


nodo actual de la cima
cima = nuevoNodo; // El nuevo nodo ahora es la cima de la pila
tamaño++; // Incrementar el tamaño de la pila
}

// Método para quitar y obtener el elemento superior de la pila (pop)


public T pop() {
if (isEmpty()) {
throw new IllegalStateException("La pila está vacía"); // Verificar si la pila está
vacía
}
T elemento = cima.elemento; // Obtener el elemento en la cima de la pila
cima = cima.siguiente; // Mover la cima de la pila al siguiente nodo
tamaño--; // Decrementar el tamaño de la pila
return elemento; // Devolver el elemento eliminado
}

// Método para obtener el elemento superior de la pila sin eliminarlo (peek)


public T peek() {
if (isEmpty()) {
throw new IllegalStateException("La pila está vacía"); // Verificar si la pila está
vacía
}
return cima.elemento; // Devolver el elemento en la cima de la pila
}

// Método para verificar si la pila está vacía


public boolean isEmpty() {
return tamaño == 0; // La pila está vacía si su tamaño es cero
}

// Método para obtener el tamaño actual de la pila


public int size() {
return tamaño; // Devolver el tamaño de la pila
}

public static void main(String[] args) {


PilaEnMemoriaDinamica pila <Integer>= new PilaEnMemoriaDinamica<>();
pila.push(1);
pila.push(2);
pila.push(3);

System.out.println("Elemento superior de la pila: " + pila.peek()); // Salida: 3


System.out.println("Tamaño de la pila: " + pila.size()); // Salida: 3

System.out.println("Desapilando elementos:");
while (!pila.isEmpty()) {
System.out.println(pila.pop());
}
// Salida:
// 3
// 2
// 1
}
}
}

Memoria Dinámica: Es un tipo de memoria que se utiliza para la asignación de


objetos y datos en tiempo de ejecución. la memoria dinámica permite crear y
administrar objetos y estructuras de datos cuya vida útil no está limitada por el
alcance de una función o método.

EXPLICACIÓN DE LOS ELEMENTOS DEL CÓDIGO (ALGORITMO)

1. Se define una clase interna Nodo para representar los elementos individuales de
la pila. Cada nodo contiene un elemento y una referencia al siguiente nodo.
2. La clase PilaEnMemoriaDinamica tiene dos campos: cima para rastrear el nodo
superior de la pila y tamaño para mantener un registro del número de elementos
en la pila.
3. El constructor de la clase inicializa la pila como vacía con cima establecido en null
y tamaño en 0.
4. El método push agrega un nuevo elemento a la pila creando un nuevo nodo,
actualizando la referencia siguiente al nodo actual de la cima y moviendo la cima
de la pila al nuevo nodo.
5. El método pop elimina y devuelve el elemento superior de la pila. Verifica si la pila
está vacía antes de hacerlo.
6. El método peek devuelve el elemento superior de la pila sin eliminarlo.
7. El método isEmpty verifica si la pila está vacía.
8. El método size devuelve el tamaño actual de la pila.
9. En el método main, se crea una instancia de la pila, se agregan elementos, se
muestra el elemento superior y se desapilan los elementos para demostrar el
funcionamiento de la pila en memoria dinámica.

PILA EN MEMORIA ESTÁTICA

package com.mycompany.practica;
public class Practica {
public class PilaEnMemoriaEstatica<T> {
private Object[] arreglo; // El arreglo para almacenar los elementos de la pila
private int tamaño; // El tamaño actual de la pila
private int capacidad; // La capacidad máxima de la pila

public PilaEnMemoriaEstatica(int capacidad) {


this.capacidad = capacidad;
arreglo = new Object[capacidad]; // Crear un arreglo con la capacidad especificada
tamaño = 0; // La pila está vacía inicialmente
}
// Método para agregar un elemento a la pila (push)
public void push(T elemento) {
if (tamaño == capacidad) {
throw new IllegalStateException("La pila está llena");
}
arreglo[tamaño++] = elemento; // Agregar el elemento en la posición actual y luego
incrementar el tamaño
}
// Método para quitar y obtener el elemento superior de la pila (pop)
public T pop() {
if (isEmpty()) {
throw new IllegalStateException("La pila está vacía");
}
@SuppressWarnings("unchecked")
T elemento = (T) arreglo[--tamaño]; // Obtener el elemento y luego decrementar el
tamaño
arreglo[tamaño] = null; // Establecer la posición vacía en null para evitar fugas de
memoria
return elemento;
}
// Método para obtener el elemento superior de la pila sin eliminarlo (peek)
public T peek() {
if (isEmpty()) {
throw new IllegalStateException("La pila está vacía");
}
@SuppressWarnings("unchecked")
T elemento = (T) arreglo[tamaño - 1]; // Obtener el elemento en la parte superior de
la pila
return elemento;
}

// Método para verificar si la pila está vacía


public boolean isEmpty() {
return tamaño == 0;
}

// Método para obtener el tamaño actual de la pila


public int size() {
return tamaño;
}

public static void main(String[] args) {


PilaEnMemoriaEstatica<Integer> pila = new PilaEnMemoriaEstatica<>(5);
pila.push(1);
pila.push(2);
pila.push(3);
System.out.println("Elemento superior de la pila: " + pila.peek()); // Salida: 3
System.out.println("Tamaño de la pila: " + pila.size()); // Salida: 3
System.out.println("Desapilando elementos:");
while (!pila.isEmpty()) {
System.out.println(pila.pop());
}
// Salida:
// 3
// 2
// 1
}}
Memoria Estática: Es el tipo de memoria que se refiere a la asignación de memoria
para variables y estructuras de datos en tiempo de compilación, antes de que el
programa se ejecute. La memoria para variables y estructuras de datos se asigna
durante la compilación del programa. Los tamaños y ubicaciones de memoria son
fijos y se conocen de antemano. Esto significa que la memoria estática es limitada
en tamaño y no se puede cambiar durante la ejecución del programa.

EXPLICACIÓN DEL ALGORITMO

1. La clase PilaEnMemoriaEstatica se define como una pila que utiliza un arreglo de


objetos (Object[]) para almacenar los elementos. La capacidad máxima de la pila
se especifica al crear una instancia de la clase.
2. El método push agrega un elemento a la pila. Antes de agregarlo, verifica si la pila
está llena (el tamaño es igual a la capacidad) y lanza una excepción en ese caso.
3. El método pop elimina y devuelve el elemento superior de la pila. Antes de
eliminarlo, verifica si la pila está vacía (el tamaño es 0) y lanza una excepción en
ese caso. También se establece la posición vacía en null para evitar fugas de
memoria.
4. El método peek devuelve el elemento superior de la pila sin eliminarlo.
5. Los métodos isEmpty y size se utilizan para verificar si la pila está vacía y para
obtener el tamaño actual de la pila, respectivamente.
6. En el método main, se crea una instancia de la pila, se agregan elementos, se
muestra el elemento superior y se desapilan los elementos para demostrar el
funcionamiento de la pila en memoria estática.
REFERENCIAS BIBLIOGRÁFICAS
 Zohonero Martínez, I. y Joyanes Aguilar, L. (2008). Estructuras de datos en
Java. Madrid etc, Spain: McGraw-Hill España. Recuperado de
https://elibro.net/es/ereader/cuautla/50117?page=293.
 GeeksforGeeks - Data Structures in Java
https://www.geeksforgeeks.org/data-structures/?ref=shm_outind
 Lafore, Robert. Estructura de Datos y Algoritmos en Java (2002), 2°
edición, Sams Publishing Editorial.

También podría gustarte