2. Implementación de pilas por medio de
listas
• La implementación de estructuras tipo pila por medio de listas constituye otro
ejemplo interesante de aplicación de estas últimas. Recordemos que las
pilas son estructuras abstractas que requieren de otras estructuras para su
implementación.
• La idea es formar una lista enlazada de eslabones que contienen los elementos de la
pila. En la clase pila se almacena la referencia al eslabón que contiene el tope de la
pila:
class Pila extends Program {
Eslabon primero= null;
void push(int x) {
primero= new Eslabon(x, primero);
}
int popInt() {
if (primero==null)
fatalError("pila vacia");
int tope= primero.x;
primero= primero.prox;
return tope;
}
}
3.
4.
5. Listas Circulares Simplemente Ligadas
Una lista circular es una lista lineal en la que el último nodo
apunta al primero.
Las listas circulares evitan excepciones en las operaciones que
se realicen sobre ellas. No existen casos especiales, cada nodo
siempre tiene uno anterior y uno siguiente. En algunas listas
circulares se añade un nodo especial de cabecera, de ese modo
se evita la única excepción posible, la de que la lista esté vacía.
Una lista circular simplemente ligada es una lista en la cual
el nodo que sigue al último es el primero. Es decir, el último
nodo tiene como sucesor al primero de la lista, logrando con ello
tener acceso nuevamente a todos los miembros de la lista.
Esta característica permite que desde cualquier nodo de
esta estructura de datos se tenga acceso a cualquiera de los
otros nodos de la misma.
6. En la imagen anterior vimos las características siguientes:
• No existe ningún nodo que apunte a null.
• La lista no tiene fin ya que al llegar al último nodo empieza de nuevo la
lista.
• Se accede a la lista mediante el primer nodo o también llamado inicio
de la lista.
• Si no se tiene cuidado al manejar la lista circular se pueden crear
bucles infinitos.
• No tiene acceso aleatorio es decir para acceder a un valor se debe
recorrer toda la lista.
7. public class Nodo {
// Variable en la cual se va a guardar el valor.
private int valor;
// Variable para enlazar los nodos.
private Nodo siguiente;
/**
• Constructor que inicializamos el valor de las variables.
*/
public void Nodo(){
this.valor = 0;
this.siguiente = null;
}
// Métodos get y set para los atributos.
public int getValor() {
return valor;
}
public void setValor(int valor) {
this.valor = valor;
}
public Nodo getSiguiente() {
return siguiente;
}
public void setSiguiente(Nodo siguiente) {
this.siguiente = siguiente;
}
}
8. Listas Doblemente
Ligadas
• una lista doblemente ligada es una estructura de datos que consiste en un
conjunto de nodos enlazados secuencialmente. Cada nodo contiene tres
campos, dos para los llamados enlaces, que son referencias al nodo siguiente
y al anterior en la secuencia de nodos, y otro más para el almacenamiento de
la información (en este caso un entero). El enlace al nodo anterior del primer
nodo y el enlace al nodo siguiente del último nodo, apuntan a un tipo de nodo
que marca el final de la lista, normalmente un nodo centinela o puntero null,
para facilitar el recorrido de la lista. Si existe un único nodo centinela,
entonces la lista es circular a través del nodo centinela.
La figura 6.13 presenta el esquema del nodo de una lista doblemente ligada.
Observe que el nodo tiene tres partes, dos de ellas dedicadas al
almacenamiento de direcciones (del nodo predecesor y del nodo sucesor) y la
tercera para guardar la información.
10. Inserción en listas doblemente ligadas
La operación de inserción de un nuevo nodo a una lista consiste en tomar un
espacio de memoria dinámicamente, asignarle la información correspondiente
y ligarlo al o a los nodos que corresponda dentro de la lista. Los pasos varían
dependiendo de la posición que ocupará el nuevo elemento.
La inserción se debe hacer a la izquierda del nodo apuntado por la posición
ofrecida a la función insertar. Esto implica que al contrario que en las listas
simples, al insertar un nodo, el puntero utilizado sigue apuntando al mismo
elemento al que apuntaba y no al nuevo elemento insertado.
12. Inserción al principio de la lista
• Se crea un nodo, cuya dirección se guarda en una variable auxiliar llamada
Apunt, a su liga derecha se le asigna la dirección del primer nodo y a la
izquierda el valor de NULL. Además, se establece la liga entre el nodo que
ocupaba la primera posición de la lista con el nuevo nodo. Por último, se
redefine el Primero con el valor de Apunt.
13. Inserción al final de la Lista
• Para ello, se crea un nuevo nodo (cuya dirección se guarda en Apunt) el cual
se liga con el último nodo de la lista. Por último, se redefine el valor del
puntero al último elemento (Ultimo) con la dirección del nuevo nodo.
14. Inserción formando una lista ordenada
La posición para el nuevo dato puede ser la primera (si es más pequeño que el
dato almacenado en el primer nodo), la última (si es más grande que el dato
almacenado en el último nodo) o una intermedia. Si fuera este último caso, se
debe encontrar la posición del nodo cuya información es mayor que la del nodo
a insertar. Una vez encontrado (Apun2), y creado el nuevo nodo (Apun1), se
establecen las ligas correspondientes entre el nuevo nodo y los que se
convertirán en su antecesor y predecesor.