Sie sind auf Seite 1von 40

1

LISTAS ENLAZADAS
UNIDAD III Ing. J.A.Cañedo
2

Ing. J.A.Cañedo

Listas enlazadas
• Utiliza posiciones de memoria no contigua para almacenar
los datos.
• Es dinámica, no tiene longitud fija, añade y elimina memoria
cuando lo necesita.
• Se apoya en otros objetos (nodos) para mantener los datos.
• Cada nodo de la lista es un objeto distinto suele haber una
clase nodo separada.
• Una lista enlazada no sabe cuantos datos almacena.
• En una lista enlazada los nodos almacenan la información.
• El orden de los elementos de la lista coincide con el orden de
los nodos en la cadena.
• El primer nodo es la cabeza o inicio de la lista.
3

Ing. J.A.Cañedo

Tipos de listas
• Listas simplemente enlazadas lineal.
• Listas simplemente enlazadas circular
• Listas doblemente enlazadas circular o lineal.
• Listas ortogonales.
4

Ing. J.A.Cañedo

• La diferencia fundamental está en el nodo que se


utiliza para llevar a cabo la implementación.
• Una lista almacenará un puntero (referencia) al
primer elemento de la lista el cual se le puede llamar
(top, cabeza, inicio).
• La posición actual se representa como un puntero
(referencia) a un nodo de la lista.
5

Ing. J.A.Cañedo
6

Ing. J.A.Cañedo

L.S.E.L.
• La lista simplemente enlazada lineal tiene un nodo
muy simple.
• El nodo pertenece a la implementación de la lista
enlazada y no a la interfaz pública de la clase.
• El primer nodo es el inicio o principio de la lista.
• Gráficamente una L.S.E.L. seria:
7

Ing. J.A.Cañedo

Representación de un nodo
Un nodo esta compuesto por dos partes principales
las cuales son el campo dato y el campo referencia
al siguiente nodo de la lista
class Nodo {
int dato;
Nodo liga;
public Nodo()
{ sig
Dato
dato=0;
sig=null;
}
public Nodo (int elem)
{
dato = elem;
sig = null;
}
}
8

Ing. J.A.Cañedo

Creación de un nodo.
La creación del nodo en C# lo hacemos al
momento de invocar al constructor de la clase
public Nodo (int elem)
{
dato = elem;
sig= null;
}
De la manera siguiente
q=new Nodo(dato);
9

Ing. J.A.Cañedo

Implementación.

• Para llevar a cabo la implementación se requiere


de lo siguiente:
 Inicio: este apuntador siempre estará
posicionado en el primer nodo de la lista.
 Final: este apuntador estará siempre
posicionado en el ultimo nodo de la lista

inicio final
10

Ing. J.A.Cañedo

Crear un L.S.E.L.
Para crear la lista se puede hacer que las inserciones se han por donde
esta posicionado el apuntador inicio en la lista como se muestra a
continuación:

public void crear_lista(ref Lista lis,int dato)


{
Nodo q=null;
if(lis.Inicio==null) //primer nodo
lis.Inicio=lis.final=new Nodo(dato);
else
{
q=new Nodo(dato);
q.sig=null;
lis.final.sig=q;
lis.final=q;
}
}
11

Ing. J.A.Cañedo

Otra manera de crear la lista es la de insertar los nodos al


final de la lista.

public void InsertarFinal(ref Lista lis,int dato)


{
Nodo q=null;
if(this.Inicio==null)
lis.Inicio=lis.final=new Nodo(dato);
else
{
q=new Nodo(dato);
lis.final.sig=q;
lis.final=q;
q=null;
}
}
12

Ing. J.A.Cañedo

Desplegar una L.S.E.L.


Para desplegar la lista basta con posicionar un apuntador al inicio de la lista e ir
recorriendo nodo por nodo hasta llegar a final como lo podemos ver en el siguiente
algoritmo:

private void button3_Click(object sender, EventArgs e)


{
Nodo q = null;
if (L1.Inicio != null) {
q = L1.Inicio;
listBox1.Items.Clear();
while(q!=null) {
listBox1.Items.Add(q.dato);
q=q.liga;
}
}
else
MessageBox.Show("La lista esta vacia");
}
13

Ing. J.A.Cañedo

Eliminar un nodo de una L.S.E.L.


• Para quitar un nodo de la lista es necesario
primeramente localizar el dato que se desea
eliminar.
• Posteriormente se actualiza el campo sig del nodo
anterior (Q) para que podamos entonces eliminar el
nodo. Como lo podemos ver a continuación suponer
que el dato a eliminar es el 4.

P
inicio final
1 2 4 5 7
Q
14

Ing. J.A.Cañedo

Algoritmo de eliminación
Procedimiento eliminar(info)
sw <- false
si inicio != null entonces
p <- inicio
mientras p!=null haz
si p(dato) = info entonces
sw <- true
si p = inicio entonces
inicio<- inicio(liga)
en caso contrario
si p=final entonces
final=q;
q(liga) <- p(liga)
p(liga) <- null
p <- null
en caso contrario
q <- p
p <- p(liga)
en caso contrario
mensaje( 'no hay lista')
si not sw entonces
mensaje('no existe información')
en caso contrario
mensaje('información borrada')
15

Ing. J.A.Cañedo

Algoritmo que cuenta el numero de nodos


de una L.S.E.L.
Se desea saber el número de nodos con que cuenta la lista,
para esto suponer que tenemos la siguiente lista:

inicio
1 2 3 5 4 8

Lo primero que tenemos que realizar es colocar un


apuntador al primer nodo de la lista y también inicializar un
contador en cero, posteriormente ir recorriendo la lista, e ir
incrementando el contador en uno por cada movimiento
que tenga el apuntador, este recorrido termina hasta que el
apuntador sea igual a null.
16

Ing. J.A.Cañedo

Continuacion
A continuación se describe el algoritmo que realiza
dicha operación.

si inicio != null entonces


i <- 0
p <- inicio
mientras p != null haz
i <- i +1
p <- p(liga)
mensaje('El numero de nodos en la lista = ', i)
en caso contrario
mensaje('no hay lista')
17

Ing. J.A.Cañedo

Algoritmo que despliega la lista de forma


invertida.
Se desea desplegar el contenido de la lista en forma inversa esto quiere
decir que se debe de recorrer la lista de derecha a izquierda. El algoritmo
seria:
si inicio!= null entonces
p = null
q=inicio
haz
q=inicio;
while (q(liga)!=p)
q=q(liga)
p <- q
escribe(p(dato))
mientras p != inicio
en caso contrario
mensaje('no hay lista')
18

Ing. J.A.Cañedo
19

Ing. J.A.Cañedo

Descripción.
Las listas circulares se desprenden de las listas descritas
anteriormente, con respecto al manejo y a su creación son
casi iguales.
Una lista circular tiene la característica que su último
nodo tiene la dirección del primer nodo de la lista, a
diferencia de la lista lineal, en donde el último nodo de la
lista apunta a null. Gráficamente una lista circular se puede
representar de la siguiente manera:
inicio
1 2 3 5 8
20

Ing. J.A.Cañedo

Operaciones básicas con L.C.


Las operaciones básicas con las listas circulares,
son las que se llevan a cabo en cualquier variable,
las cuales son:
• Creación.
• Inserción.
• Eliminación.
• Desplegar
• Ordenar
21

Ing. J.A.Cañedo

Algoritmo que crea una L.C.


public void Crear(ref ListaCirc lis, int dato)
{
Nodo q = new Nodo(dato);
if (lis.Inicio == null)

lis.Inicio = lis.ult = q;
else
{
lis.ult.liga= q;
lis.ult = q;
}
q.sig = lis.Inicio;
}
22

Insertar un nodo Ing. J.A.Cañedo

después de x dato. public void InsertarDespues(ref ListaCirc Lis, int X, int dato)
{
inicio 6
Nodo p = null, q = null;
1 2 3 5 8 if (Lis.Inicio != null)
{
p = Lis.Inicio;
Se desea insertar el nodo con el dato 6 do
{
que se encuentra con líneas azules en if (p.dato == X)
la lista después del nodo cuya {
información es 3, el algoritmo seria: q = new Nodo(dato);
q.liga = p.liga;
p.liga = q;
if (p == Lis.ult)
Lis.ult = p;
p = Lis.Inicio;
}
else
p = p.liga;
} while (p != Lis.Inicio);
}
else
MessageBox.Show("No existe lista circular");
}
23

Insertar un nodo antes Ing. J.A.Cañedo

de x dato en L.C. public void InsertarAntes(ref ListaCirc Lis, int X, int dato)
{
Nodo p = null, q = null, r = null;
if (Lis.Inicio != null)
{
p = Lis.Inicio;
Otra situación diferente a la anterior, do
{
es la de insertar el nodo antes del if (p.dato == X)
nodo cuya información es 3, como se {
q = new Nodo(dato);
muestra a continuación: q.liga = p;
if (p == Lis.Inicio)
{
Lis.Inicio = q;
Lis.ult.liga = Lis.Inicio;
p.liga = q;
6 }
inicio ult else
r.liga = q;
p = Lis.Inicio;
1 3 5 }
else
{
r = p;
p = p.liga;
}
} while (p != Lis.Inicio);
}
}
24

Ing. J.A.Cañedo

Algoritmo de eliminación de un nodo


en una L.C.
Supongamos que tenemos la siguiente lista
circular:
inicio
1 2 3 6 5 8

El cual se desea eliminar el nodo cuya información


sea 1. La lista nos quedaría de la siguiente manera:
inicio
2 3 6 5 8
25

Ing. J.A.Cañedo

Procedimiento eliminar(entero x)
El algoritmo que realiza la si inicio != null entonces
tarea de eliminar el nodo con x p <- inicio;
sw <- false
datos seria: haz
si p(dato) = x entonces
sw <- verdadero
si p = inicio entonces
si inicio(liga) = inicio entonces
inicio<- nil
en caso contrario
ult(liga) <- inicio(liga)
inicio<- inicio(liga)
en caso contrario
q(liga) <- p(liga)
si ult=p entonces
ult=q
p->liga <- null
p <- inicio
en caso contrario
q <- p
p <- p(liga)
mientras p != inicio
si sw entonces
mensaje(´nodo borrado´)
en caso contrario
mensaje(´no existe información ´)
en caso contrario
mensaje(´no existe lista´)
26

Ing. J.A.Cañedo

Alg. que ordena una L.C.


Suponga que se tiene la siguiente si inicio != null entonces
lista circular: p <- inicio
inicio haz
q <- p(liga)
2 3 6 5 8
mientras q != inicio haz
si p(dato) > q(dato) entonces
x <- q(dato)
El cual se desea ordenarla de q(dato) <- p(dato)
manera ascendente. El algoritmo p(dato) <- x
que se describe a continuación, q <- q(liga)
ordena la lista circular, moviendo p <- p(liga)
mientras p(liga) != inicio
únicamente la información del
en caso contrario
nodo. escribe(´no existe lista´)
inicio
2 3 5 6 8
27

Ing. J.A.Cañedo

Algoritmo que despliega una L.C.


si inicio != null entonces
p <- inicio
haz
escribe(p(dato))
p <- p(liga)
mientras p != inicio
en caso contrario
mensaje(´no existe lista´)
28

Ing. J.A.Cañedo
29

Ing. J.A.Cañedo

Descripción.
Las listas doblemente encadenadas, tienen las característica
de que dado un apuntador p posicionado en cualquier nodo
que forme parte de la lista, esta puede ser examinada en
ambos sentidos, esto es de adelante hacia atrás y de atrás
hacia adelante.
Un nodo en una lista doblemente encadenada tiene dos
apuntadores, uno hacia el nodo siguiente y otro hacia el
nodo anterior, como lo podemos apreciar a continuación:
der
izq B
30

Ing. J.A.Cañedo

Tipos de L.D.E.
Existen dos tipos de lista doblemente encadenadas
las cuales son :
• Circulares
A B C

• Lineales.
A B C
31

Ing. J.A.Cañedo

Alg. que crea una L.D.E.C.


top <- null
haz
mensaje('Desea crear un nodo S/N=')
leer(opc)
si opc = 's' entonces
si inicio= null entonces
inicio <- crear nodo()
leer(inicio(dato))
inicio(izq) <- inicio
inicio(der) <- inicio
en caso contrario
p <- crear nodo()
leer(p(dato)
p(der) <- inicio
p(izq) <- inicio(izq)
p(der(izq)) <- p
inicio(izq) <- p
hasta opc != 'N'
32

Ing. J.A.Cañedo

Algoritmo que recorre una L.D.E.C.

si inicio != null entonces


p <- inicio
haz
escribe(p(dato))
p <- p(der)
mientras p = top
en caso contrario
mensaje('Lista inexistente')
33

Ing. J.A.Cañedo

Alg. que inserta un nodo después de x


dato.
si inicio != null Then
mensaje(‘Después de que dato quieres insertar=')
leer(x)
p <- inicio
haz
si p(dato) = x entonces
q <- crear nodo()
leer(q(dato))
q(der) <- p(der)
q(izq) <- p
p(izq(der)) <- q
p(der) <- q
en caso contrario
p <- p(der)
mientras (p != inicio o sw)
en caso contrario
mensaje('No existe lista')
34

Ing. J.A.Cañedo

Alg que elimina un nodo con x dato.


si inicio != null entonces
mensaje('Información a borrar')
leer(info)
p <- inicio
haz
si p(dato) = info entonces
si p=inicio entonces
si inicio(der) = inicio entonces
inicio <- null
en caso contrario
inicio <- inicio(der)
p(izq(der)) <- p(izq)
p(der(izq)) <- p(der)
p(der) <- null
p(izq)<- null
en caso contario
p <- p(der)
mientras (p != inicio o sw)
en caso contrario
mensaje('Lista inexistente')
35

Ing. J.A.Cañedo

Alg que ordena una L.D.E.C. moviendo


apuntadores.
si inicio != null entonces
p <- inicio
haz
q <- p(der)
haz
si p(dato) > q(dato) entonces
si p = inicio entonces
inicio<- q
q(der(izq)) <- q(der)
q(izq(der)) <- q(izq)
r <- q(der)
q(der) <- p
q(izq) <- p(izq)
q(izq(der)) <- q
q(der(izq)) <- q
p <- q
r <- q
en caso contrario
q <- q(der)
mientras q != inicio
en caso contrario
mensaje(‘no hay lista’)
36

Ing. J.A.Cañedo
37

Ing. J.A.Cañedo

Descripción.
Las listas ortogonales son estructuras que se emplean en el
área de ingeniería donde se manejan matrices demasiado
grandes. Al trabajar con este tipo de estructuras, estamos
hablando de una gran cantidad de elementos, donde dichos
elementos se pueden crear, modificar e incluso destruir
cuando lo desee, lo que no sucede con los arreglos ya que
estos son estáticos esto es que durante toda la ejecución del
programa serán siempre del mismo tamaño, teniendo como
consecuencia un desperdicio de memoria, si la totalidad de
los elementos del arreglo no fueron utilizados, o en el caso
contrario de que se requiere más elementos de los que tiene
declarados. Es por eso de que surgen las listas ortogonales
en donde se puede manejar la longitud de la matriz.
38

Ing. J.A.Cañedo

Representación grafica de un nodo de


una L.O.
Cada nodo de una lista ortogonal esta compuesto
por un campo dato y por cuatro campos de tipo
apuntado así como se muestra en la siguiente
figura: arr

der
dato
izq

aba
39

Ing. J.A.Cañedo

Representación grafica de una L.O.C.


Una lista ortogonal seria: Nodos de
encabezamientos

* * *

Nodos de
encabezamientos
* 2 3 4

* 1 5 7

* 9 2 6
40

Alg que crea una L.O.C. Ing. J.A.Cañedo

void CreaListOrt() if(tren==NULL)


{ {
int nr, nc; tren=p; tren->aba=tren; tren->arr=tren;
int i,j, x,y; }
nodo *p, *q, *c, *r; else
clrscr(); {
tren=NULL; tcol=NULL; p->aba=tren; p->arr=tren->arr;
gotoxy(2,3);printf("Numero de Renglones=");scanf("%d",&nr); p->aba->arr=p;
gotoxy(2,4);printf("Numero de Columnas=");scanf("%d",&nc); p->arr->aba=p;
for(i=1; i<=nc; i++) }
{ }
p=new nodo; c=tcol; r=tren; y=6;
p->dato='*'; for(i=1; i<=nr; i++)
p->arr=p; p->aba=p; {
if(tcol==NULL) x=6;
{ for(j=1; j<=nc; j++)
tcol=p; {
tcol->der=tcol; tcol->izq=tcol; p=new nodo;
} gotoxy(x,y); p->dato=getche();
else p->der=r; p->izq=r->izq;
{ p->der->izq=p;
p->der=tcol; p->izq=tcol->izq; p->izq->der=p;
p->der->izq=p; p->aba=c; p->arr=c->arr;
p->izq->der=p; p->aba->arr=p;
} p->arr->aba=p;
} c=c->der;
for(j=1; j<=nr; j++) x+=4;
{ }
p=new nodo; r=r->aba; c=tcol; y+=2;
p->dato='*'; }
p->izq=p; p->der=p; }

Das könnte Ihnen auch gefallen