. Unidad 4: CONTENEDORES LINEALES 1 Tema:LISTAS ENLAZADAS 1. INTRODUCCION. 2. REPRESENTACION DE DATOS EN MEMORIA. 3. ORGANIZACIÓN DE DATOS: LISTAS CON ENLACE SIMPLE (DATOS DESORDENADOS Y DATOS ORDENADOS) (Apuntes de apoyo a clases teóricas) Tiempo de exposición: 2 hs Bibliografía: 2 1. Seymour Lipschutz. Estructuras de datos. Editorial Mc Graw Hill. Año 1987. 2. Aho, Hopcroft y Ullman. Estructuras de datos y Algoritmos. Editorial Addison Wesley. Año 1988. 3. Luis Joyanes Aguilar. Fundamentos de Programación: Algoritmos y Estructuras de Datos. Editorial Mc Graw Hill .1988. 4. Apuntes de la cátedra – Dr. Tomas N. Hibbard. 5. Videos de la cátedra – Dr. Tomas N. Hibbard. Objetivos de la clase: 3 1. Con el TAD LISTA: realizar la Implementación con Lista Enlazada, proponer una estructura de datos, sus operaciones y realizar el análisis de su complejidad. 2. Extraer conclusiones respecto a la utilización de una u otra implementación. TAD LISTA 4 Con Arreglos o Arrays (Asignación Estática de Memoria) (Datos Desordenados y Ordenados) CLASE ANTERIOR Listas Implementación o representación en Memoria Con Punteros (Asignación Dinámica de Memoria) Con Listas Enlazadas: (Datos Desordenados y Ordenados) Con Cursores (Asignación Estática de Memoria) IMPLEMENTACION DE LISTAS: Con Listas Enlazadas 5 1) Asignación Dinámica de Memoria (Punteros) 2) Asignación Estática de Memoria (Cursores) IMPLEMENTACION DE LISTAS: Con Listas Enlazadas 6 1) Asignación Dinámica de Memoria (Punteros) Algunos lenguajes como Pascal, C, C++, Java permiten implementar listas enlazadas mediante punteros. IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 7 1. Una lista está formada por una colección lineal de elementos, llamados nodos. 2. Tenemos un primer y un ultimo nodo, de tal manera que a cada nodo, salvo el ultimo, le corresponde un único sucesor, y a cada nodo, salvo el primero, le corresponde un único predecesor. 3. El orden de los elementos se establece mediante punteros o enlaces. 4. Cada nodo tiene dos partes, conteniendo: - la información asociada al elemento: campo de dato - la dirección del siguiente nodo de la lista: campo de enlace. 5. El campo de enlace del último nodo contiene un valor especial, llamado valor nulo (nil) y señala el final de la lista. 6. Existe un nodo especial INICIO, cuyo campo de enlace indica el comienzo de la lista enlazada y contiene la dirección del primer nodo. 7. Si la lista está vacía, EL CAMPO DE ENLACE DE INICIO contiene un valor nulo. Esquemáticamente el nodo: Dato campo de dato nodo campo de enlace o puntero o siguiente IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 8 Esquemáticamente: la lista … Nil inicio Primer nodo de la lista Ultimo nodo de la lista Esquemáticamente: el último nodo la lista 9 Nil Ejemplo de lista enlazada (datos desordenados y repetidos): 5 inicio 1 5 9 Nil IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 9 Estructura de Datos: Para almacenar una lista enlazada, necesitaremos: - La estructura de un nodo: un registro, con dos campos (dato y siguiente) - El inicio de la lista: un variable del tipo enlace, llamada Inicio o Lista Declaraciones en Pascal para esta estructura: 9 Type Nodo = Record dato: Tipo_elemento; sig: ^Nodo End; Lista = ^Nodo; Posicion = ^Nodo; El valor nulo en Pascal es la palabra reservada NIL IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 10 Algunas operaciones sobre esta estructura: 1. Recorrer(L:Lista): Recorre la lista hasta el final mostrando sus elementos Procedure Recorrer(L: Lista); Var i: ^Nodo; Begin i := L; {inicio de la lista} While ( i <> Nil ) do Begin writeln(‘Elemento:’,i^ .dato; i := i^.sig; End; End; 5 5 1 9 Nil L i i i i i=Nil IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 11 Algunas operaciones sobre esta estructura: 2. Ultimo(L:Lista): devuelve un puntero al último nodo Function Ultimo(L: Lista): Posicion; Var i: ^Nodo; Begin i := L; {inicio de la lista} If ( i <> Nil ) do | Begin While ( i^.sig <> Nil ) do i := i^.sig; Ultimo := i; End Else writeln (‘Lista vacía, no tiene último elemento’ End; 5 5 1 9 L i i i i Nil IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 12 3. Vacia(L:Lista): Testea si la lista L está vacía Function Vacia(L: Lista): Boolean Begin If L = Nil then Vacia := True else Vacia := False; End; Nil L IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 13 4. Insertar (x:Tipo_elemento, p:Posición, L:lista): Casos: a) La lista L está vacía Luego de la inserción: Nil L x p Nil L b) La lista L tiene elementos: b.1) La inserción se realiza al principio de la lista 5 L P=Nil x Nil nuevo 1 9 Nil IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 14 4. Insertar (x:Tipo_elemento, p:Posición, L:lista): Casos: b) La lista L tiene elementos: p b.2) La inserción se realiza al final de la lista: 5 1 9 Nil x Nil L nuevo b.3) La inserción se realiza entre dos nodos: 5 L 1 p x Nil nuevo 9 Nil IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 15 4. Insertar(x:Tipo_elemento; p:Posición; Var L:Lista) Inserta x luego del nodo apuntado por p: Procedure Insertar(x:Tipo_Elemento; p: Lista; Var L:Lista); Var Nuevo, i:Lista; Begin New(nuevo); Nuevo^.dato := x; Nuevo^.sig := Nil; If L <> Nil then begin if p = Nil then begin {inserta antes del primer nodo de la lista} nuevo^.sig:=L; L:=Nuevo; end else begin {inserta luego del nodo apuntado por p} i:= p^.sig; Nuevo^.sig := i; p^.sig := nuevo; end; end else L:= nuevo; {la lista L estaba vacía} End; IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) Pruebas 16 Procedure Insertar(x:Tipo_Elemento; p: Lista; Var L:Lista); Var Nuevo, i:Lista; Begin New(nuevo); Nuevo^.dato := x; Nuevo^.sig := Nil; If L <> Nil then begin if p = Nil then begin {inserta antes del primer nodo de la lista} nuevo^.sig:=L; L:=Nuevo; end else begin {inserta luego del nodo apuntado por p} i:= p^.sig; Nuevo^.sig := i; p^.sig := nuevo; end; end else L:= nuevo; End; a) La lista L está vacía: Nil L p p es Nil i Nil Y luego de la inserción L: x L p nuevo Nil IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 17 Procedure Insertar(x:Tipo_Elemento; p: Lista; Var L:Lista); Var Nuevo, i:Lista; Begin New(nuevo); Nuevo^.dato := x; Nuevo^.sig := Nil; If L <> Nil then begin if p = Nil then begin {inserta antes del primer nodo de la lista} nuevo^.sig:=L; L:=Nuevo; end else begin {inserta luego del nodo apuntado por p} i:= p^.sig; Nuevo^.sig := i; p^.sig := nuevo; end; end else L:= nuevo; End; b.1) La lista contiene elementos y la inserción es al principio: 5 1 L P= Nil x 9 Nil IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 18 Procedure Insertar(x:Tipo_Elemento; p: Lista; Var L:Lista); Var Nuevo, i:Lista; Begin New(nuevo); Nuevo^.dato := x; Nuevo^.sig := Nil; If L <> Nil then begin if p = Nil then begin {inserta antes del primer nodo de la lista} nuevo^.sig:=L; L:=Nuevo; end else begin {inserta luego del nodo apuntado por p} i:= p^.sig; Nuevo^.sig := i; p^.sig := nuevo; end; end else L:= nuevo; End; b.2) La inserción se realiza al final de la lista 5 1 9 Nil L p i Nil x Nil nuevo IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 19 Procedure Insertar(x:Tipo_Elemento; p: Lista; Var L:Lista); Var Nuevo, i:Lista; Begin New(nuevo); Nuevo^.dato := x; Nuevo^.sig := Nil; If L <> Nil then begin if p = Nil then begin {inserta antes del primer nodo de la lista} nuevo^.sig:=L; L:=Nuevo; end else begin {inserta luego del nodo apuntado por p} i:= p^.sig; Nuevo^.sig := i; p^.sig := nuevo; end; end else L:= nuevo; End; b.3) La inserción se realiza entre dos nodos 5 1 L p i x nuevo 9 Nil IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 20 5. Eliminar (x:Tipo_elemento, L:lista): (pred apunta al anterior) Casos: a) La lista L está vacía Nil No se puede eliminar x !!! L pred b) La lista L tiene elementos: b.1) La eliminación se realiza al principio de la lista x L Pred=Nil 1 9 Nil IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 21 5. Eliminar (x:Tipo_elemento, L:lista): Casos: b) La lista L tiene elementos: b.2) La eliminación se realiza al final de la lista 5 L 1 pred x Nil 9 Nil Nil b.3) La eliminación se realiza entre dos nodos 5 L pred x IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 22 5. Eliminar(x:Tipo_elemento; Var L:Lista) (busca el nodo que contiene a x y lo elimina) Procedure Eliminar(x:tipo_Elemento;var L:Lista); {elimina el nodo que contiene a x} Var i,p,pred: Lista; encontrado:Boolean; Begin i:= L; pred:=Nil; encontrado := False; While (not(Vacia(i))) and Not(encontrado) do if (i^.dato = x) then begin encontrado := True; p:= i; if (pred = Nil) then L:=L^.sig {se elimina el primer nodo de L} else pred^.sig :=i^.sig; dispose(p); end else begin pred := i; i:=i^.sig; end; if not(encontrado) then writeln('elemento no existe, no se pudo eliminar'); End; IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 23 Pruebas de Eliminar según los distintos casos: Procedure Eliminar(x:tipo_Elemento;var L:Lista); {elimina el nodo que contiene a x} Var i,p,pred: Lista; encontrado:Boolean; Begin i:= L; pred:=Nil; encontrado := False; While (not(Vacia(i))) and Not(encontrado) do if (i^.dato = x) then begin encontrado := True; p:= i; if (pred = Nil) then L:=L^.sig {se elimina el primer nodo de L} else pred^.sig :=i^.sig; dispose(p); end else begin pred := i; i:=i^.sig; end; if not(encontrado) then writeln('elemento no existe, no se pudo eliminar'); End; a) La lista L está vacía: Nil L Encontrado:= False Elemento no existe, no se puedo eliminar IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 24 Procedure Eliminar(x:tipo_Elemento;var L:Lista); {elimina el nodo que contiene a x} Var i,p,pred: Lista; encontrado:Boolean; Begin i:= L; pred:=Nil; encontrado := False; While (not(Vacia(i))) and Not(encontrado) do if (i^.dato = x) then begin encontrado := True; p:= i; if (pred = Nil) then L:=L^.sig {se elimina el primer nodo de L} else pred^.sig :=i^.sig; dispose(p); end else begin pred := i; i:=i^.sig; end; if not(encontrado) then writeln('elemento no existe, no se pudo eliminar'); End; b.1) La lista contiene elementos y la eliminación es al principio: x L Pred = Nil i 1 p 9 Nil IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 25 Procedure Eliminar(x:tipo_Elemento;var L:Lista); {elimina el nodo que contiene a x} Var i,p,pred: Lista; encontrado:Boolean; Begin i:= L; pred:=Nil; encontrado := False; While (not(Vacia(i))) and Not(encontrado) do if (i^.dato = x) then begin encontrado := True; p:= i; if (pred = Nil) then L:=L^.sig {se elimina el primer nodo de L} else pred^.sig :=i^.sig; dispose(p); end else begin pred := i; i:=i^.sig; end; if not(encontrado) then writeln('elemento no existe, no se pudo eliminar'); End; b.2) La eliminación se realiza al final de la lista 5 L pred i x 1 Nil p Nil IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 26 Procedure Eliminar(x:tipo_Elemento;var L:Lista); {elimina el nodo que contiene a x} Var i,p,pred: Lista; encontrado:Boolean; Begin i:= L; pred:=Nil; encontrado := False; While (not(Vacia(i))) and Not(encontrado) do if (i^.dato = x) then begin encontrado := True; p:= i; if (pred = Nil) then L:=L^.sig {se elimina el primer nodo de L} else pred^.sig :=i^.sig; dispose(p); end else begin pred := i; i:=i^.sig; end; if not(encontrado) then writeln('elemento no existe, no se pudo eliminar'); End; b.3) La eliminación se realiza entre dos nodos 5 L pred 9 x p Nil IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 27 6. Buscar(x:Tipo_elemento, L:Lista): devuelve un puntero al nodo donde se encuentra x, sino Nil. Function Buscar(x:Tipo_Elemento, L: Lista): Posicion; Var i: Lista; Encontrado : Boolean; Begin i = Nil; If not (vacia(L)) then begin Encontrado := False; i := L; {inicio de la lista} While ( i <> Nil and Encontrado = False) do if i^.dato = x then Encontrado := True else i := i^.sig; End; Buscar := i; End; IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 28 6. Buscar(x:Tipo_elemento, L:Lista): Function Buscar(x:Tipo_Elemento, L: Lista): Posicion; Var i: Lista; Encontrado : Boolean; Begin i = Nil; If not (vacia(L)) then begin Encontrado := False; i := L; {inicio de la lista} While ( i <> Nil and Encontrado = False) do if i^.dato = x then Encontrado := True else i := i^.sig; End; Buscar := i; End; Buscar(9, L): 5 L 1 5 9 X IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 29 6. Buscar(x:Tipo_elemento, L:Lista): devuelve un puntero al nodo donde se encuentra x , sino Nil. (RECURSIVO) o bien un valor booleano podría ser. Function Buscar(x:Tipo_Elemento, L: Lista): Posicion; Begin If (L= Nil) then Buscar:=Nil Else If ( L^.dato = x) then Buscar := L else Buscar: =Buscar(x, L^.sig); End; Buscar(9, L): 5 5 1 9 L i i i i X IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 30 7. Longitud (L:Lista): devuelve la cantidad de nodos de la lista. La recursividad subyacente en la definición del tipo de datos lista hace que la definición de la función Longitud en forma recursiva sea muy simple y clara: Function Longitud(L:Lista): Integer; Begin If L = nil then Longitud:= 0 else Longitud := 1 + Longitud(L^.sig); End; Se deja como ejercicio la definición no recursiva de Longitud. IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Punteros) 31 Para finalizar la implementación de la lista con Punteros, se deja como ejercicio la implementación de las operaciones: Vaciar(L), Primero(L), Siguiente(p,L), Anterior(p,L) y Recuperar(p,L) para hacer ejecutable el procedimiento PURGAR(L) Se sugiere en las clases prácticas utilizar Lenguajes Pascal y C para especificar el TAD Lista y luego un programa que las utilice. Próximo tema: Implementación de Listas: enlazadas con cursores IMPLEMENTACION DE LISTAS: Con Listas Enlazadas 32 2) Asignación Estática de Memoria (Cursores) Algunos lenguajes como Fortran, Cobol, NO permiten implementar listas enlazadas mediante asignación dinámica de memoria (punteros). IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Cursores) 33 Características: 1. Se puede simular el mecanismo de lista enlazada mediante cursores. 2. Qué son los cursores? - Números enteros que indican posiciones en arreglos estáticos. Variable Inicio:= Prox(0) Variable Nuevo:=2 0 1 2 3 4 f j 6 0 a 1 8 5 5 6 7 h 7 4 0 8 Posición c X 3 Prox Esquemáticamente: la lista de elementos y de espacio disponible Prox(0) a c f Nuevo Existe un orden en la lista: X[i] < X [ Prox [i] ] h x j X IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Cursores) 34 Estructura de Datos: Para almacenar una lista enlazada con cursores, necesitaremos 2 arrays: - X: almacena la información - Prox: almacena nro entero que es el índice del siguiente elemento - El inicio de la lista de elementos: variable de tipo entero - El inicio de la lista de disponibles: variable de tipo entero Declaraciones en Pascal para esta estructura: TYPE Elementos= Array[0..Long_max] of Tipo_elemento; Enlaces = Array[0..Long_max] of Integer; 34 VAR X: Elementos; Prox : Enlaces; Inicio : Integer; Nuevo: Integer; IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Cursores) 35 Algunas Operaciones: Function Buscar(t: Tipo_Elemento; X: Elementos; Prox:Enlaces): Boolean; Begin Buscar:= Buscar1(t,X,Prox, Prox[0]) End; Function Buscar1(t:Tipo_Elemento; X:Elementos; Prox:Enlaces; i:Integer) : Boolean; Begin If i = 0 then Buscar1:= False Else If X[i] = t then Buscar1:= True Else If X[i] < t then Buscar1:=Buscar1(t, X, Prox, Prox [i] ) Else Buscar1:=False End; IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Cursores) 36 Ejemplo: Function Buscar(t: Tipo_Elemento; X: Elementos; Prox:Enlaces): Boolean; Begin Buscar:= Buscar1(t,X,Prox, Prox[0]) End; Function Buscar1(t:Tipo_Elemento; X:Elementos; Prox:Enlaces; i:Integer) : Boolean; Begin If i = 0 then Buscar1:= False Else If X[i] = t then Buscar1:= True Else Else Buscar1:=False; End; Variable Inicio:= Prox(0):=1 Variable Nuevo:= 2 0 If X[i] < t then Buscar1:=Buscar1(t, X, Prox, Prox [i] ) 1 2 a 1 8 5 3 4 f j 6 0 5 6 7 h 7 4 0 8 Posiciones c X 3 Prox Buscar(“f”,X,Prox) = Buscar1(“f”,X,Prox,1) = i=1; X[1] = “a” < “f” => Buscar1(“f”,X,Prox,8) = i=8; X[8] = “c” < “f” => Buscar1(“f”,X,Prox,3) = Prox[1] = 8 Prox[8] = 3 i=3; X[3] = “f” = “f” => True Prox[3] = 6 IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Cursores) 37 Algunas Operaciones: Procedure Insertar(t: Tipo_Elemento; VAR X: Elementos; VAR Prox:Enlaces); Begin Insertar1(t,X,Prox, 0, Prox[0], Nuevo) End; Procedure Insertar1(t:Tipo_Elemento; VAR X:Elementos; VAR Prox:Enlaces; VAR Pred:Integer; VAR i:Integer; Var Nuevo:Integer); Begin If (i <> 0) and (X[i] = t) then Writeln(‘Elemento repetido’) Else If (i ≠ 0) and (t > x [i]) then iinsertar1 (t, x, prox, i, Prox[i], nuevo) Else If (Nuevo <>0) then Begin g := prox[nuevo]; prox[nuevo] := i; prox[Pred] := nuevo; X[Nuevo] := t; Nuevo := g; End; IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Cursores) Ejemplo 38 Procedure Insertar(t: Tipo_Elemento; VAR X: Elementos; VAR Prox:Enlaces); Begin Insertar1(t,X,Prox, 0, Prox[0], Nuevo) End; Procedure Insertar1(t:Tipo_Elemento;VAR X:Elementos;VAR Prox:Enlaces; VAR Pred:Integer; VAR i:Integer; VAR Nuevo:Integer); Begin If (i <> 0) and (X[i] = t) then Writeln(‘Elemento repetido’) Else If (i ≠ 0) and (t > x [i]) then Insertar1 (t, x, prox, i, Prox[i], nuevo) Else If (Nuevo <>0) then Begin g := prox[nuevo]; prox[nuevo] := i; prox[Pred] := nuevo; X[Nuevo] := t; Nuevo := g; End; Variable Inicio:= Prox(0):=1 Variable Nuevo:= 2 0 1 2 a 1 8 5 3 4 f j 6 0 5 6 7 h 7 4 0 8 Posiciones c X 3 Prox Insertar(“b”,X,Prox) = Insertar1(“b”,X,Prox,0,1,2) = g = Prox[2]=5 i=1; X[1] = “a” < “b” =>Insertar1(“b”,X,Prox,1, 8, 2) = Prox[2]=8 i=8; X[8] = “c” > “b” => Nuevo <> 0 => Prox[1]=2 Prox[1] = 8 Prox[8] = 3 X[2]=“b” IMPLEMENTACION DE LISTAS: Con Listas Enlazadas (Cursores) 39 Luego de insertar “b”, la lista queda de la siguiente manera: Variable Inicio:= Prox(0):=1 Variable Nuevo:=5 0 1 Prox(0) a Nuevo b 1 2 3 4 a b f j 2 8 6 0 c 5 6 7 h 7 4 f 0 h x MANTENIENDO EL ORDEN EN LA LISTA: X[i] < X [ Prox [i] ] 8 Posiciones c X 3 Prox j X IMPLEMENTACION DE LISTAS: Con Listas Enlazadas 40 Análisis de Complejidad: n: cantidad de elementos en la lista C(n) = función de complejidad Operación Mejor Caso Caso Promedio Peor Caso Buscar (Secuencial) El elemento está primero en El elemento está El elemento está al la lista: en el medio de final de la lista o no la lista está C(n) = 1 C(n) = n / 2 C(n) = n Insertar C(n) = Nro de movimiento de punteros + buscar C(n) = Nro de movimiento de punteros + buscar C(n) = Nro de movimiento de punteros + buscar Eliminar C(n) = nro mov de punteros + buscar C(n) =nro mov de punteros + buscar C(n) = nro mov de punteros + buscar Lista con un solo elemento C(n) = 1 _____ Lista con n elementos C(n) = n Final Conclusiones: Implementar Listas con Arrays y/o Punteros ? 41 1. Cuando las inserciones o eliminaciones sean frecuentes, conviene utilizar la implementación con Listas Enlazadas, ya que no existe desplazamiento. 2. Cuando se conoce de antemano el tamaño de los datos (n) y ésta es pequeña conviene utilizar la implementación con Arreglos. 3. Las listas enlazadas requieren un espacio de memoria adicional para los enlaces. 4. Acceder al k-ésimo elemento de la lista implementada con arreglos es más rápido que tener que recorrer secuencialmente una estructura enlazadas hasta el k-ésimo nodo. Por lo tanto vemos que la técnica de enlaces que nos libera de las limitaciones impuestas por las posiciones contiguas de memoria, nos proporciona mayor rendimiento en algunas operaciones, mientras que en otras perdemos rendimiento, Para finalizar la clase de hoy …. 42 Repasemos lo visto: El TAD LISTA: Implementación con Lista Enlazada (Punteros y Cursores): estructura de datos, operaciones y análisis de su complejidad. ARRAYS Lineales: Listas LISTAS ENLAZADAS. Estructuras de datos ARRAYS No lineales. Grafos, Arboles LISTAS ENLAZADAS.