2. LISTAS: OPERACIONES
BASICAS CrearLista()
EliminarLista(L)
Referencia_Nodo ConsultarPrimero(L)
Referencia_Nodo ConsultarUltimo(L)
bool EstaVacia(L)
bool EstaLlena(L)
Dada la Lista L, InsertarNodoInicio(L, C)
la posición P y InsertarNodoFinal(L, C)
InsertarNodoAntesDe(L, P, C)
la información C Referencia_Nodo EliminarPrimero(L)
Referencia_Nodo EliminarUltimo(L)
EliminarNodo(L, P)
Referencia_Nodo BuscarNodo(L, C)
Referencia_Nodo PosAnterior(L, P)
Recorrer(L)
3. TDA: LISTAS DOBLEMENTE
ENLAZADAS
En las listas enlazadas solo se avanza en un sentido
En las doblemente, se puede avanzar hacia la derecha o hacia la izq.
En estas listas cada nodo tiene
Un predecesor, excepto el primero
Un sucesor, excepto el ultimo
Cada nodo ya no tiene un solo enlace, tiene dos, hacia el siguiente y hacia el
anterior
<lde> ::= <comienzo> + {<nodo>}+<ultimo>
<comienzo> :: = <enlace>
<ultimo> :: = <enlace>
<enlace> ::= (<<referencia_nodo>> | NULL)
<nodo> ::= <predecesor>+<contenido>+<sucesor>
<predecesor> ::= <enlace>
<sucesor> ::= <enlace>
< contenido > ::= <<dato>>{<<dato>>}
4. LDE: IMPLEMENTACION
header last
10 5 8 25 2 31
Cuando la lista
esta vacia,
D I D typedef struct LDE_Nodo {
A S typedef struct { header y last,
Generico G; son iguales a
struct LDE_nodo *sig; LDE_Nodo *header; NULL
struct LDE_nodo *ant; LDE_Nodo *last;
} LDE_nodo ; }LDE;
5. last = nuevo
INSERTAR NODOS last
nuevo
nuevo->ant = last
header header->ant = nuevo last 15
header
header
nuevo 10 5 21 12 17 6
15 last->sig = nuevo
nuevo->sig = header
bool LDE_InsertarNodoFin (LDE *L,
header = nuevo
LDE_nodo *nuevo){
bool LDE_InsertarNodoInicio(LDE *L, LDE_nodo *nuevo){
if(!nuevo) return FALSE;
if(!nuevo) return FALSE;
if(LDE_EstaVacia(*L)) L->header = L->last = nuevo; if(LDE_EstaVacia(&L))
else{ L->header = L->last = nuevo;
nuevo->sig = L->header; else{
L->header->ant = nuevo; nuevo->ant = L->last;
L->header = nuevo;
L->last->sig = nuevo;
}
L->last = Nuevo;
return TRUE;
} }
return FALSE;
}
8. LISTAS CIRCULARES
El avance en las listas enlazadas es
Solo a la derecha(siguiente)
Limitado hasta el ultimo nodo
Hay ocasiones en las que se desearia,
Poder avanzar ilimitadamente
Del ultimo nodo, pasar al primero
last->siguiente = header
last->sig last
10 5 8 25 2 31
9. EL TDA LISTA CIRCULAR
No es necesario mantener un control de:
Primero y ultimo
Solo con el ultimo ya se tiene todo, pues
last ->siguiente es igual a header
typedef struct LCE_nodo{
Generico G; typedef LCE_nodo *LCE;
struct LCE_nodo *sig;
}LCE_nodo;
10. CREAR NODO
Para crear un nodo valido
LCE_Nodo * LCE_Nodo_Crear(Generico G){
LCE_Nodo *nuevo;
nuevo = malloc(sizeof(LCE_Nodo));
nuevo->G = G;
I D
nuevo->sig = nuevo; S
return nuevo;
}
11. LOCALIZA
LCE_nodo *LC_Buscar(LCE *L, Generico G,
Generico_Comparar fn){
LCE_nodo *p;
if(LCE_EstaVacia(*L)) return NULL;
p = L;
do{
if(fn(p->G, G) == 0) return(p); Busco 25
13
p = p->sig;
}while(p!= L);
p p
return(NULL); p
p
} p p pp pp
last->sig last
10 5 8 25 2 31
12. ANTERIOR
Es buscar el anterior a un nodo dado
LCE_Nodo *LCE_Anterior(LCE *L, LCE_nodo *p){
LCE_Nodo *q;
if(LCE_EstaVacia(L) || p== NULL) LCE_Anterior = NULL;
q = L;
do{
if(q->sig == p) return(q);
q = q->sig;
}while(q!=L);
return(NULL);
}
13. nuevo->sig = last->sig
INSERTAR INICIO Y FIN last
nuevo
last->sig last->sig = nuevo last
10
10 5 8 25 2 31
last = nuevo
bool LCE_InsertarNodoInicio(LCE *L, bool LCE_InsertarNodoFin(LCE *L,
LCE_nodo *nuevo ){ LCE_Nodo *nuevo){
if(nuevo == NULL) return FALSE; if(nuevo == NULL) return FALSE;
if(LCE_EstaVacia(*L)) L = nuevo; if(LCE_EstaVacia(L)) L = nuevo;
else{
else{
nuevo->sigt = L->sig;
nuevo->sig = L->sig;
L->sig = nuevo;
L->sig = nuevo;
}
}
L = nuevo;
return TRUE;
return TRUE;
} }
16. LISTAS CIRCULARES
DOBLEMENTE ENLAZADAS
Es una implementacion de listas circulares
Con nodos que tienen dos punteros
Asi se recorre la lista en el
Sentido del avance del reloj y
En sentido contrario
Seguimos llevando un control solo del ultimo nodo de la
lista
last
10 5 8 25 2 31
17. RECORRER LISTA
Escribir una operación Recorre_R que recorre una lista cir. Dobl.
Enla. Hacia atras
void LCDE_Recorre_R(LCDE L, Generico_Imprimir fn){
LCDE_nodo *pos;
if(!LCDE_EstaVacia(L)) return;
pos = L;
while(TRUE){
pos = pos->ant;
if(pos == L) break;
fn(pos->G);
}
}