listas especiales estructuras de datos. listas: operaciones basicas crearlista() eliminarlista(l)...
TRANSCRIPT
LISTAS ESPECIALES
Estructuras de Datos
LISTAS: OPERACIONES BASICAS CrearLista()
EliminarLista(L) Referencia_Nodo ConsultarPrimero(L) Referencia_Nodo ConsultarUltimo(L) bool EstaVacia(L) bool EstaLlena(L) InsertarNodoInicio(L, C) InsertarNodoFinal(L, C) InsertarNodoAntesDe(L, P, C) Referencia_Nodo EliminarPrimero(L) Referencia_Nodo EliminarUltimo(L) EliminarNodo(L, P) Referencia_Nodo BuscarNodo(L, C) Referencia_Nodo PosAnterior(L, P) Recorrer(L)
Dada la Lista L,
la posición P y
la información C
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>>}
LDE: IMPLEMENTACION
typedef struct {
LDE_Nodo *header;
LDE_Nodo *last;
}LDE;
typedef struct LDE_Nodo {
Generico G;
struct LDE_nodo *sig;
struct LDE_nodo *ant;
} LDE_nodo ;
Cuando la lista esta vacia,
header y last, son iguales a
NULL
I DSDA
last
header
10 5 8 25 2 31
10 5 21 12 17 6
INSERTAR NODOS
bool LDE_InsertarNodoInicio(LDE *L, LDE_nodo *nuevo){
if(!nuevo) return FALSE;
if(LDE_EstaVacia(*L)) L->header = L->last = nuevo;
else{
nuevo->sig = L->header;
L->header->ant = nuevo;
L->header = nuevo;
}
return TRUE;
}
bool LDE_InsertarNodoFin (LDE *L,
LDE_nodo *nuevo){
if(!nuevo) return FALSE;
if(LDE_EstaVacia(&L))
L->header = L->last = nuevo;
else{
nuevo->ant = L->last;
L->last->sig = nuevo;
L->last = Nuevo;
}
return FALSE;
}
last
header
nuevo->sig = header
header->ant = nuevo
header
header = nuevo
nuevo
15
nuevo->ant = last
last->sig = nuevo
last
last = nuevo
nuevo
15
header
INSERTAR ENTRE
bool LDE_InsertarNodo(LDE *L, LDE_nodo *p, LDE_nodo *nuevo){
if (!p || !LDE_Existe(*L,P)) return FALSE;
if(LDE_EstaVacia(*L) || p==L->last) LDE_InsertarNodoFin(L,nuevo); else { if(!nuevo) return FALSE; nuevo->sgt = p->sgt; p->sgt = nuevo; nuevo->sgt->ant = nuevo; nuevo->ant = p; } return TRUE;}
header last
10 5 21 12 17 6
p
nuevo
15nuevo->sig = p->sig;
p->sig = nuevo
nuevo->ant = p
nuevo->sig->ant = nuevo
ELIMINAR NODOS
LDE_nodo *LDE_EliminarxPos (LDE *L, LDE_nodo *p){
if(!p || !LDE_Existe(L,P)) return NULL;
if(p==L->header){
return(LDE_SacarNodoInicio(L));
} else if (P==L->last){
return(LDE_SacarNodoFin(L));
}
else {
p->ant->sig = p->sig;
p->sig->ant = p->ant;
}
return p;
}
10 5 21 12 17 6
header last
p
p->ant->sig = p->sig;
P->sig->ant = p->ant
free(p);
tmp = L->header;
L->header = L->header->sig;
L->header->ant = NULL;
return(tmp);
tmp= L->last;
L->last = L->last->ant;
L->last->sig = NULL;
return(tmp);
LDE_nodo *LDE_EliminarxInfo(LDE *L,
Generico G, Generico_Comparar fn){
LDE_Nodo *p ;
if(EstaVacia(L)) return;
p = LDE_Buscar(L,G, fn);
if (!p) return NULL;
return(LDE_EliminarxPos(L,P);)
}
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
10 5 8 2 3125
last->sig last
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;
struct LCE_nodo *sig;
}LCE_nodo;
typedef LCE_nodo *LCE;
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;
nuevo->sig = nuevo;
return nuevo;
}
I DS
LOCALIZALCE_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);
p = p->sig;
}while(p!= L);
return(NULL);
}
10 5 8 2 3125
last->sig last
Busco 25
p
pp
Busco 13
p
pppp
p p
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);
}
INSERTAR INICIO Y FIN
bool LCE_InsertarNodoInicio(LCE *L,
LCE_nodo *nuevo ){
if(nuevo == NULL) return FALSE;
if(LCE_EstaVacia(*L)) L = nuevo;
else{
nuevo->sig = L->sig;
L->sig = nuevo;
}
return TRUE;
}
bool LCE_InsertarNodoFin(LCE *L,
LCE_Nodo *nuevo){
if(nuevo == NULL) return FALSE;
if(LCE_EstaVacia(L)) L = nuevo;
else{
nuevo->sigt = L->sig;
L->sig = nuevo;
}
L = nuevo;
return TRUE;
}
10 5 8 2 3125
last->sig last
nuevo->sig = last->sig
10
nuevolast->sig = nuevo
last
last = nuevo
INSERTAR EN MEDIObool LCE_Insertar(LCE *L, LCE_Nodo *P, LCE_Nodo *nuevo){
if(P == NULL || !LCE_Existe(*L,P)) return FALSE;
if(LCE_EstaVacia(*L) || p==L) LCE_InsertarNodoFin(L,nuevo);
else {
nuevo->sig = P->sig;
P->sig = Nuevo;
}
return TRUE;
}
ELIMINA
LCE_Nodo * LCE_EliminarxInfo(LCE *L, Generico G,Generico_Comparacion fn){
LCE_Nodo *p ;
if(LCE_EstaVacia(*L)) return 0;
p = LCE_Buscar(*L,I,fn);
if(p == NULL) return 0;
return(LCE_EliminarxPos(L,p));
}
LCE_Nodo *LCE_EliminarxPos(LCE *L, LCE_nodo *p){
LCE_Nodo *elminado, *ant;
if(p == NULL || !LCE_Existe(*L,p))
return NULL;
if(L ==L->sig){
L = NULL;
return(L);
} else if (p==L){
return(LCE_SacarNodoFin(L));
}
else {
ant = LCE_Anterior(*L,p);
ant->sig = p->sig;
return(p);
}
}
eliminado = L
ant = LCE_Anterior(L,L);
ant->sig = L->sig;
L = ant;
return(eleminado);
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
10 5 8 25 2 31
last
RECORRER LISTA Escribir una operación Recorre_R que recorre una lista cir. Dobl.
Enla. Hacia atrasvoid 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);
}
}