You are on page 1of 29

Temas

• Clasificación y operaciones en listas encadenadas

Administración de Proyectos de desarrollo de Software


LISTAS ENCADENADAS
Ciclo de vida de un proyecto
Enfoque moderno
Fin de la presentación

Continúe en la siguiente actividad

Administración de Proyectos de desarrollo de Software


LISTAS ENCADENADAS
Ciclo de vida de un proyecto
Enfoque moderno
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

Las listas se pueden dividir en cuatro categorías:


1. Listas simplemente encadenadas.- cada nodo (elemento) contiene un
único enlace que conecta ese al nodo siguiente o sucesor. La lista es
eficiente en recorridos directos (adelante).
2. Listas doblemente encadenadas.- cada nodo contiene dos enlaces,
uno a su nodo predecesor y el otro a su sucesor. La lista es eficiente
tanto en recorrido directo (adelante) como en recorrido inverso (atrás).
3. Lista circular simplemente encadenada.- Una lista enlazada
simplemente en la que el último elemento (cola) se enlaza al primer
elemento (cabeza) de tal modo que la lista puede ser recorrida de
modo circular (en anillo).
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

4. Lista circular doblemente encadenada.- Una lista doblemente


encadenada en la que el último elemento se enlaza al primer elemento
y viceversa. Esta lista se puede recorrer de modo circular (en anillo)
tanto en dirección directa (adelante) como inversa (atrás).

• Por lo tanto una lista encadenada consta de un conjunto de nodos. Un


nodo consta de un campo dato y un apuntador al siguiente elemento
de la lista.

dato siguiente dato siguiente dato siguiente dato

cabeza ptr_actual cola


LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

• El primer nodo, frente, es el nodo apuntado por cabeza. La lista


encadena nodos juntos desde el frente al final (cola) de la lista. El final
se identifica como el nodo cuyo campo apuntador tiene el valor NULL =
0.
• La lista recorre desde el primero al último nodo; en cualquier punto del
recorrido la posición actual se referencia por el apuntador ptr_actual. En
el caso en que la lista no contiene un nodo (está vacía), el apuntador
cabeza es nulo.

cabeza

NULL
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

Operaciones en listas encadenadas


• Una lista encadenada requiere unos controles para la gestión de los
elementos contenidos en ellas. Estos controles se manifiestan en forma
de operaciones que tendrán las siguientes tareas:
 Inicialización o creación, con declaración de los nodos
 Insertar elementos en una lista
 Eliminar elementos de una lista
 Buscar elementos de una lista
 Recorrer una lista encadenada
 Comprobar si la lista está vacía
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

Declaración de un nodo
• En C++ se puede definir un nodo mediante un nuevo tipo de dato con las
palabras reservadas struct o class que contiene las dos partes de un
nodo:
struct Nodo class Nodo {
{ public:
int dato; int dato;
Nodo *enlace; Nodo *enlace;
}; // constructor
};
• La definición puede utilizar struct, que es un tipo especial de clase. De
hecho, si se cambia la palabra reservada struct por class, la definición
sigue siendo la misma.
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

• La diferencia sutil, es que en una estructura struct los miembros son


siempre públicos, mientras que en una estructura class los miembros
son, por defecto, privados a menos que se ponga delante de ellos la
palabra public.

• Dado que los tipos de datos que se pueden incluir en una lista pueden
ser de cualquier tipo (enteros, reales, caracteres o incluso cadenas), con
el objeto de que el tipo de dato de cada nodo pueda cambiar con
facilidad, se suele utilizar una sentencia typedef para definir el nombre
de elemento como un sinónimo del tipo de dato de cada cadena, como
se muestra a continuación:
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas


struct nodo
{
typedef double elemento;
elemento dato;
nodo *enlace;
};

• Entonces, si se necesita cambiar el tipo de elemento en los nodos, sólo


tendrá que cambiar la sentencia de definición de tipos que afecta a
elemento.
Apuntador de cabecera y cola
• Normalmente, los programas no declaran realmente variables de nodos.
En su lugar, cuando se construye y manipula una lista encadenada, a la
lista se accede a través de uno o más apuntadores a los nodos.
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas


• El acceso más frecuente a una lista encadenada es a través del primer nodo de
la lista que se llama cabeza o cabecera de la lista.
• Un apuntador al primer nodo se llama apuntador cabeza, y el último nodo de la
lista es la cola y un apuntador al último nodo es el apuntador cola.

• 23.5 • 40.7 • 21.7

ptr_cabeza

• ptr_cola

Definición del nodo


struct nodo
{ Declaración de apuntadores
typedef double elemento; nodo *ptr_cabeza;
elemento dato; nodo *ptr_cola;
nodo *enlace;
}
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

El apuntador nulo
• Se utiliza, normalmente, en dos situaciones:
 Usar el apuntador nulo en el campo de enlace o siguiente del nodo final de
la lista encadenada.
 Cuando una lista encadenada no tiene ningún nodo, se utiliza el apuntador
NULL como apuntador de cabeza y de cola. Esta lista se denomina lista
vacia. Por ejemplo:
nodo *ptr_cabeza;
ptr_cabeza = NULL;

• 23.5 • 40.7 • 21.7 NULL

ptr_cabeza
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

El operador -> de selección de un miembro


• Si p es un apuntador a una clase (o una estructura) y m es un miembro de la
clase, entonces p -> m accede al miembro m de la estructura apuntado por p.
• P -> m significa lo mismo que (*p).m
Construcción de una lista
Pasos:
1. Declarar el tipo de dato y el apuntador de cabeza o primero.
2. Asignar memoria para un elemento del tipo definido anteriormente utilizando el
operador new; la dirección del nuevo elemento es ptr_nuevo.
3. Crear iterativamente el primer elemento (cabeza) y los elementos sucesivos
de una lista encadenada simplemente.
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

4. Repetir hasta que no haya más entrada para el elemento.


Por ejemplo:
Crear una lista encadenada de elementos que almacenen datos de tipo
entero.
Primero definimos un elemento
class Elemento {
´ public:
Elemento *siguiente;
int dato;
Elemento (Elemento *n, int d) : siguiente (n), dato (d) { } // constructor
};
El siguiente paso para construir la lista es declarar la variable primero que
apuntará al primer elemento de la lista:
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

Elemento *Primero = NULL o bien


• El apuntador Primero (también se puede llamar Cabeza) se ha inicializado a un
valor nulo, lo que implica que la lista está vacía (no tiene elementos).
• Ahora se crea un elemento de la lista y se sitúa en la lista con la operación:
Primero = new Elemento (Primero, 5);

• 5 NULL
primero

• El apuntador Primero apunta al nuevo elemento que se inicializa por el


constructor de la clase Elemento. Dado que el apuntador tenía un valor de nulo
(cero) el campo siguiente del nuevo elemento tomará el valor nulo.
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

• Si ahora se desea añadir un nuevo elemento con un valor de 3 y situarlo en el


primer lugar de la lista se escribe simplemente:
Primero = new Elemento (Primero, 3);

• 3 • 5 NULL

• Por último, para obtener una lista 4, 3, 5 se habrá de ejecutar:


Primero = new Elemento (Primero, 4);

• 4 • 3 • 5
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

Insertar un elemento en la lista


• Para añadir o insertar un elemento en una lista encadenada varía dependiendo
de la posición en que se desea insertar el elemento. La posición de inserción
puede ser:
 En la cabeza (elemento primero) de la lista.
 En el final de la lista (elemento último).
 Antes de un elemento especificado.
 Después de un elemento especificado.
Insertar un nuevo elemento en la cabeza de una lista
• Aunque normalmente se insertan nuevos datos al final de una estructura de
datos, es más fácil y más eficiente insertar un elemento nuevo en la cabeza de
una lista.
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

• El proceso de inserción se puede resumir de la siguiente manera:


Asignar un nuevo nodo apuntado por insertar_ptr que es una variable
apuntador local que apunta al nuevo nodo que se va a insertar en la lista.
Situar el nuevo elemento en el campo dato(Info) del nuevo nodo.
Hacer que el campo enlace siguiente del nuevo nodo apunte a la cabeza
(primer nodo) de la lista original.
Hacer que cabeza_ptr (apuntador cabeza) apunte al nuevo nodo que se
ha creado.
• Por ejemplo: una lista encadenada contiene tres elementos, 8, 25, 78.
insertar un nuevo elemento 4 en la cabeza de la lista:
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

• 8 • 25 • 78 NULL

• Pasos 1 y 2

• 4
insertar_ptr

• 8 • 25 • 78

cabeza_ptr

Código C++
insertar_ptr = new Nodo;
insertar_ptr -> dato = entrada;
• Paso 3.- el campo enlace (siguiente) del nuevo nodo apunta a la cabeza actual de la lista.
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

• Clasificación y operaciones en listas encadenadas

• 4 •
insertar_ptr
8 • 25 • 78


cabeza_ptr

Código C++: insertar_ptr -> siguiente = cabeza_ptr;

Paso 4. se cambia el apuntador de cabeza para apuntar al nuevo nodo creado; es decir,
el apuntador de cabeza apunta al mismo sitio que apunta insertar_ptr.

Código C++: cabeza_ptr = insertar_ptr;


LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas


insertar_ptr 4 • 8 • 25 • 78 NULL


cabeza_ptr

• En este momento, la función de insertar un elemento en la lista termina su


ejecución y la variable local insertar_ptr desaparece y sólo permanece el
apuntador cabeza_ptr que apunta a la nueva lista.

• 4 • 8 • 25 • 78 NULL

cabeza_ptr
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

• El código fuente de la función InsertarCabezaLista es:


void InsertarCabezaLista(Nodo& cabeza_ptr, const Nodo :: Item& entrada)
{
Nodo *insertar_ptr;
insertar_ptr = new Nodo; // asigna nuevo nodo
insertar_ptr -> dato = entrada; // pone elemento en nuevo nodo
insertar_ptr -> siguiente = cabeza_ptr; // enlaza nuevo nodo al frente de la lista
cabeza_ptr = insertar_ptr; // mueve apuntador cabeza y apunta al
} // nodo

Inserción de un nuevo nodo que no esta en la cabeza de lista


• Se desea insertar un nuevo elemento 75 entre el elemento 25 y el elemento 78
en la lista encadenada 8, 25, 78.
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

• 8 • 25 • 78 NULL

75 •

• Pasos:
Asignar un nuevo nodo apuntado por el apuntador insertar_ptr.
Situar el nuevo elemento en el campo dato (Info) del nuevo nodo).
Hacer que el campo enlace siguiente del nuevo nodo apunte al nodo que va
después de la posición del nuevo nodo (o bien a NULL si no hay ningún nodo
después de la nueva posición).
Crear un apuntador al nodo que está antes de la posición deseada para el nuevo
nodo y hacer que anterior_ptr -> siguiente apunte al nuevo nodo que acaba de
crear.
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

• Pasos 1 y 2: se crea un nuevo nodo que contiene a 75


anterior_ptr •

8 • 25 • 78 NULL
• no se utiliza
cabeza_ptr

• 75 •
insertar_ptr

Código C++ insertar_ptr = new Nodo;


insertar_ptr - > dato = entrada;

• Paso 3
Código C++ insertar_ptr -> siguiente = anterior_ptr -> siguiente;
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

anterior_ptr

8 • 25 • 78 NULL

• 75 •
insertar_ptr
Paso 4
anterior_ptr •

8 • 25 • 78 NULL

insertar_ptr • 75 •
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

• Después de ejecutar todas las sentencias de los pasos la nueva lista


comenzaría en el nodo 8 , seguiría en 25, 75 y, por último 78.
• El código fuente quedaría:
void InsertarLista(Nodo *anterior_ptr, cont Nodo::Item& entrada)
{
Nodo *insertar_ptr;
insertar_ptr = new Nodo;
insertar_ptr -> dato = entrada;
insertar_ptr -> siguiente = anterior_ptr -> siguiente;
anterior_ptr -> siguiente = insertar_ptr;
}
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas


Inserción al final de la lista
• La inserción al final de la lista es menos eficiente debido a que,
normalmente, no se tiene un apuntador al último elemento de la lista y
entonces se ha de seguir la traza de la lista hasta el último nodo de la
lista y, a continuación, realizar la inserción.
• Cuando último es una variable apuntador que apunta al último nodo de
la lista, las sentencias siguientes insertan un nodo al final de la lista:
ultimo -> siguiente = new nodo;
ultimo -> siguiente -> dato = entrada;
ultimo -> siguiente -> siguiente = NULL;
• La primer sentencia asigna un nuevo nodo que está apuntado por el
campo siguiente al último nodo de la lista (antes de la inserción) de
modo que el nuevo nodo ahora es el último nodo de la lista. La tercer
sentencia establece el campo siguiente del nuevo último nodo a NULL.
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

Eliminación de un nodo en una lista


• La operación eliminar un nodo de una lista supone enlazar el nodo
anterior con el nodo siguiente que se desea eliminar y liberar la
memoria que se ocupa.
Pasos:
Búsqueda del nodo que tiene el dato. Se ha de tener la dirección del
nodo a eliminar y la dirección del anterior.
El apuntador siguiente del nodo anterior ha de apuntar al siguiente del
nodo a eliminar.
En caso del nodo a eliminar sea el primero, cabeza, se modifica
cabeza para que tenga la dirección del nodo siguiente.
Por último, se libera la memoria ocupada por el nodo.
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas

• Código fuente de eliminarLista es:


void eliminarLista(Nodo &cabeza_ptr, *siguiente_ptr const Nodo :: Item &entrada)
{
Nodo *actual_ptr, *anterior_ptr;
int encontrado = 0;
acrual_ptr = *cabeza_ptr; anterior_ptr = NULL;
while ((actual_ptr != NULL) && (!encontrado) // ciclo de búsqueda
{
encontrado = (actual_ptr -> dato == entrada);
if (!encontrado)
{
anterior_ptr = actual_ptr;
actual_ptr = actual_ptr -> siguiente_ptr;
}
}
LISTAS ENCADENADAS

Clasificación y operaciones en listas encadenadas


// enlace de nodo anterior con siguiente
if (actual_ptr != NULL)
{ // se distingue entre que el nodo sea el cabecera o del resto de la lista
if (actual == *cabeza_ptr)
{
*cabeza_ptr = actual_ptr -> siguiente_ptr;
}
else
{
anterior_ptr -> siguiente_ptr = actual_ptr -> siguiente_ptr;
}
delete(actual_ptr);
}
}

You might also like