Tema 8: 8: Estructuras datos. Fundamentos Informática 1º Ingeniería Industrial Escuela Superior Ingenieros Universidad Sevilla Ismael Alcalá Torrego José Ángel Acosta Rodríguez Fernando Dorado Navas Fabio Gómez Estern-Aguilar Manuel López Martínez Amparo Núñez Reyes Carlos Vivas Venegas
TEMA TEMA 8: 8: Estructuras Estructuras datos. datos. Lista enlazada = Estructura datos lineal, formada por bloques información, con un formato común, enlazados entre sí mediante punteros. INICIO LISTA Bloque 1 Bloque 2 Bloque 3 Bloque 4 FIN Características Características listas listas Los elementos se distribuyen forma dispersa por la memoria: Los bloques información no ocupan posiciones consecutivas en la memoria. El orn la lista la establecen los enlaces entre bloques información. Acceso a los elementos aleatorio: Pue extraerse información cualquier elemento o insertar un bloque en cualquier posición. Acceso a los elementos no structivo: Al contrario que en colas y pilas, la extracción un bloque no implica su eliminación. El tamaño la lista pue modificarse forma dinámica: Al contrario que en colas y pilas, no hay un número máximo elementos la lista (salvo limitaciones la capacidad almacenamiento la máquina)
Cada elemento contiene un enlace con el siguiente elemento la lista. Conocida la posición un elemento, pomos recorrer la lista hacia lante No es posible recorrer la lista hacia atrás. INICIO LISTA Bloque 1 Bloque 2 Bloque 3 Bloque 4 en en C struct direc char nombre[40]; char calle[40]; char ciudad[20]; int codigo; struct direc * sig; info; Información l Elemento Enlace con el siguiente elemento Por convenio, el fin lista se indica como Puntero a la propia estructura Cada elemento requiere una reserva dinámica memoria al ser creado (liberar memoria al ser eliminado). La gestión la lista se hace con funciones apropiadas para añadir, insertar, borrar, buscar elementos, etc.
Construcción Construcción una una Lista Lista enlazada enlazada en en C Lista Desornada Dos Formas Lista Ornada No hay orn específico para los elementos. La lista se construye añadiendo cada nuevo elemento al final la lista existente. Si no existe lista, el nuevo elemento pasa a ser el primero y único la lista. Los elementos se añan para que la lista final tenga un orn específico. Hay que buscar el punto inserción l elemento según el orn establecido. La inserción pue ser al principio, en medio o al final. Si no existe lista, el nuevo elemento pasa a ser el primero y único la lista. raiz Elto 1 Elto 2 Elto 3 raiz Elto 1 Elto 2 Elto 3 nuevo elemento AL FINAL nuevo elemento INSERCIÓN raiz Elto 1 Elto 2 Elto 3 nuevo raiz Elto 1 Elto 2 nuevo Elto 3
1.- Lista Desornada struct direc * almac_fin( struct direc *top, struct direc * nuevo) struct direc * p = top; /* puntero que recorrerá la lista hasta el final */ if (top = = ) /* si no existe lista la crea */ return nuevo ; while( p -> sig ) /* recorre la lista hasta que p apunte al último */ p = p -> sig ; p -> sig = nuevo; /* enlaza el nuevo elemento al final */ return top; /* vuelve la cabeza */ top Elto. 1 Elto. 2 Elto. 3 nuevo E. nuevo
1.- Lista Desornada struct direc * almac_fin( struct direc *top, struct direc * nuevo) struct direc * p = top; /* puntero que recorrerá la lista hasta el final */ if (top = = ) /* si no existe lista la crea */ return nuevo ; while( p -> sig ) /* recorre la lista hasta que p apunte al último */ p = p -> sig ; p -> sig = nuevo; /* enlaza el nuevo elemento al final */ return top; /* vuelve la cabeza */ Recibe: -Puntero al comienzo la lista top -Puntero al nuevo elemento a insertar nuevo top Elto. 1 Elto. 2 Elto. 3 (Se be haber reservado memoria dinámicamente antes llamar a la función) nuevo E. nuevo
1.- Lista Desornada struct direc * almac_fin( struct direc *top, struct direc * nuevo) struct direc * p = top; /* puntero que recorrerá la lista hasta el final */ if (top = = ) /* si no existe lista la crea */ return nuevo ; while( p -> sig ) /* recorre la lista hasta que p apunte al último */ p = p -> sig ; p -> sig = nuevo; /* enlaza el nuevo elemento al final */ return top; /* vuelve Devuelve: la cabeza */ -Puntero al comienzo la lista (En este caso la cabecera la lista sólo varía al insertar el primer elemento) top Elto. 1 Elto. 2 Elto. 3 nuevo E. nuevo
1.- Lista Desornada struct direc * almac_fin( struct direc *top, struct direc * nuevo) struct direc * p = top; /* puntero que recorrerá la lista hasta el final */ if (top = = ) /* si no existe lista la crea */ return nuevo ; while( p -> sig ) /* recorre la lista hasta que p apunte al último */ p = p -> sig ; p -> sig = nuevo; /* enlaza Si el principio el nuevo elemento la lista es al final, */ la lista no return top; /* vuelve la cabeza */ existe y la creamos: Su primer elemento es el que le pasamos, nuevo, y es también la nueva cabecera la lista. nuevo top top E. nuevo La lista no existe El nuevo Elto es el primero y único la lista
1.- Lista Desornada Si el principio la lista no es, la lista ya tiene al menos un elemento. struct direc * almac_fin( struct direc Recorremos *top, struct la lista direc hasta * nuevo) encontrar el último elemento (Al salir l while, p apunta al último struct direc * p = top; /* puntero elemento) que recorrerá la lista hasta el final */ if (top = = ) /* si no existe lista la crea */ return nuevo ; while( p -> sig ) /* recorre la lista hasta que p apunte al último */ p = p -> sig ; p -> sig = nuevo; /* enlaza el nuevo elemento al final */ return top; /* vuelve la cabeza */ top Elto. 1 Elto. 2 Elto. 3 p nuevo E. nuevo
1.- Lista Desornada Alcanzado el final la lista, sólo queda enlazar el nuevo elemento a continuacíón struct direc * almac_fin( struct direc éste. *top, struct direc * nuevo) (El siguiente elemento al último (p->sig) berá struct direc * p = top; /* puntero apuntar que recorrerá a nuevo) la lista hasta el final */ if (top = = ) /* si no existe lista la crea */ return nuevo ; while( p -> sig ) /* recorre la lista hasta que p apunte al último */ p = p -> sig ; p -> sig = nuevo; /* enlaza el nuevo elemento al final */ return top; /* vuelve la cabeza */ top Elto. 1 Elto. 2 Elto. 3 p nuevo E. nuevo
1.- Lista Desornada struct direc * almac_fin( struct direc *top, struct direc * nuevo) Para finalizar volvemos la cabecera la lista (Haya ésta cambiado o no) struct direc * p = top; /* puntero que recorrerá la lista hasta el final */ if (top = = ) /* si no existe lista la crea */ return nuevo ; while( p -> sig ) /* recorre la lista hasta que p apunte al último */ p = p -> sig ; p -> sig = nuevo; /* enlaza el nuevo elemento al final */ return top; /* vuelve la cabeza */ top Elto. 1 Elto. 2 Elto. 3 E. nuevo
2.- Lista Ornada struct Estructura Estructura ciclista base base *insertar para para el ( el struct ejemplo ejemplo ciclista la la * función función top, struct insertar insertar ciclista * nuevo) struct struct struct ciclista ciclista *actual = top; /* puntero para moverse por la lista */ struct ciclista int intnum; *anterior num; /* /* número número = ; l l /*puntero ciclista ciclista */ al */ elemento anterior al "actual" */ /* Búsqueda char char l nombre[80]; punto nombre[80]; inserción /* /* nombre nombre */ l l ciclista ciclista */ */ while ( (actual int inttiempo;!= tiempo; ) /* /*&& tiempo tiempo (actual en en la -> la clasificación tiempo clasificación <= nuevo */ */ -> tiempo) ) anterior = struct actual; structciclista ciclista ** sig; sig; /* /* puntero puntero a siguiente siguiente */ */ actual = actual ; ; -> sig; /* El inserción El objetivo objetivo */ es es diseñar diseñar la la función función insertar insertar para para crear crear listas listas if ornadas (anterior ornadas!= ) elementos elementos /* inserción struct struct en ciclista. ciclista. medio o final */ anterior El El criterio criterio -> sig ornación = ornación nuevo; será será menor menor a a mayor mayor tiempo tiempo else clasificación. /* clasificación. inserción al principio la lista */ top = nuevo; nuevo -> sig = actual; return top; /* vuelve la cabecera la lista */
2.- Lista Ornada struct ciclista *insertar ( struct ciclista * top, struct ciclista * nuevo) struct ciclista *actual = top; /* puntero para moverse por la lista */ struct ciclista *anterior = ; /*puntero al elemento anterior al "actual" */ /* Búsqueda l punto inserción */ while ( (actual!= ) && (actual -> tiempo <= nuevo -> tiempo) ) anterior = actual; actual = actual -> sig; /* Inserción */ if (anterior!= ) /* inserción en medio o final */ Recibe: -Puntero al comienzo la lista top -Puntero al nuevo elemento a insertar nuevo anterior -> sig = nuevo; (Se be haber reservado memoria dinámicamente else /* inserción al principio antes la llamar lista */ a la función) top = nuevo; nuevo -> sig = actual; return top; /* vuelve la cabecera la lista */
2.- Lista Ornada struct ciclista *insertar ( struct ciclista * top, struct ciclista * nuevo) struct ciclista *actual = top; /* puntero para moverse por la lista */ struct ciclista *anterior = ; /*puntero al elemento anterior al "actual" */ /* Búsqueda l punto inserción */ while ( (actual!= ) && (actual -> tiempo <= nuevo -> tiempo) ) anterior = actual; actual = actual -> sig; Devuelve: /* Inserción */ -Puntero al comienzo la lista if (anterior!= ) /* inserción en medio o final */ anterior -> sig = nuevo; (En este caso la cabecera la lista varía si el else /* inserción al nuevo principio elemento la lista tiene */ un tiempo clasificación top = nuevo; inferior a todos los más) nuevo -> sig = actual; return top; /* vuelve la cabecera la lista */
struct ciclista *insertar ( struct ciclista * top, struct ciclista * nuevo) struct ciclista *actual = top; /* puntero para moverse por la lista */ struct ciclista *anterior = ; /*puntero al elemento anterior al "actual" */ /* Búsqueda l punto inserción */ while ( (actual!= ) && (actual -> tiempo <= nuevo -> tiempo) ) anterior = actual; actual = actual -> sig; /* Inserción */ if (anterior!= ) /* inserción en medio o final */ - anterior, que apunta al elemento precente a actual anterior -> sig = nuevo; else /* inserción al principio la lista */ Elto 4 Elto 5 top = nuevo; nuevo -> sig = actual; return top; /* vuelve la cabecera la lista */ 2.- Lista Ornada Recorreremos la lista con dos punteros: -actual que apunta al elemento que queremos examinar en ese momento top Elto 1 Elto 2 Elto 3 anterior actual
2.- Lista Ornada struct ciclista *insertar ( struct ciclista * top, struct ciclista * nuevo) struct ciclista *actual = top; /* puntero para moverse por la lista */ struct ciclista *anterior = ; /*puntero al elemento anterior al "actual" */ /* Búsqueda l punto inserción */ while ( (actual!= ) && (actual -> tiempo <= nuevo -> tiempo) ) anterior = actual; actual = actual -> sig; /* Inserción */ if (anterior!= ) /* inserción Recorremos en medio o final la lista */ s el principio anterior -> sig = nuevo; mientras: else /* inserción al principio la lista */ top = nuevo; 1.- No lleguemos al final nuevo -> sig = actual; return top; /* vuelve la cabecera la lista */
2.- Lista Ornada struct ciclista *insertar ( struct ciclista * top, struct ciclista * nuevo) struct ciclista *actual = top; /* puntero para moverse por la lista */ struct ciclista *anterior = ; /*puntero al elemento anterior al "actual" */ /* Búsqueda l punto inserción */ while ( (actual!= ) && (actual -> tiempo <= nuevo -> tiempo) ) anterior = actual; actual = actual -> sig; Y 2.- El elemento actual tenga un tiempo clasificación /* Inserción */ inferior al l nuevo elemento. if (anterior!= ) /* inserción en medio o final */ Si no es así, el nuevo elemento be insertarse entre los anterior -> sig = nuevo; elementos la lista apuntados por anterior y actual. else /* inserción al principio la lista */ top = nuevo; top Elto 1 Elto 2 Elto 3 Elto 4 Elto 5 nuevo -> sig = actual; return top; /* vuelve la cabecera anterior la nuevo lista */ actual
2.- Lista Ornada Una vez localizado el punto inserción, hay que distinguir dos casos: struct ciclista *insertar ( struct ciclista * top, struct ciclista * nuevo) 1.- Que el punto inserción sea en medio o al final struct ciclista *actual = top; /* puntero para moverse por la lista */ struct ciclista *anterior = ; top /*puntero Elto 1 al elemento Elto 2 Eltoanterior 3 4al "actual" */ /* Búsqueda l punto inserción */ while ( (actual!= ) && (actual -> tiempo <= nuevo -> tiempo) ) anterior nuevo actual anterior = actual; actual = actual -> sig; /* Inserción */ if (anterior!= ) /* inserción en medio o final */ anterior -> sig = nuevo; else /* inserción al principio la lista */ top = nuevo; nuevo -> sig = actual; return top; /* vuelve la cabecera la lista */
2.- Lista Ornada En cuyo caso Reconectamos como struct ciclista *insertar ( struct ciclista * top, struct ciclista * nuevo) top Elto 1 Elto 2 Elto 3 Elto 4 struct ciclista *actual = top; /* puntero para moverse por la lista */ struct ciclista *anterior = ; /*puntero al elemento anterior al "actual" */ anterior actual nuevo /* Búsqueda l punto inserción */ while ( (actual!= ) && (actual -> tiempo <= nuevo -> tiempo) ) anterior -> sig = nuevo anterior = actual; actual = actual -> sig; /* Inserción */ if (anterior!= ) /* inserción en medio o final */ anterior -> sig = nuevo; else /* inserción al principio la lista */ top = nuevo; nuevo -> sig = actual; return top; /* vuelve la cabecera la lista */
2.- Lista Ornada struct ciclista *insertar ( struct ciclista * top, struct ciclista * nuevo) struct ciclista *actual = top; /* puntero para moverse por la lista */ struct ciclista *anterior = ; /*puntero al elemento anterior al "actual" */ /* Búsqueda l punto Si noinserción */ while ( (actual!= ) && (actual -> tiempo <= nuevo -> tiempo) ) 2.- La inserción es al principio la lista. anterior = actual; actual = actual -> sig; /* Inserción */ if (anterior!= ) /* inserción en medio o final */ anterior -> sig = nuevo; else /* inserción al principio la lista */ top = nuevo; nuevo -> sig = actual; return top; /* vuelve la cabecera la lista */
2.- Lista Ornada En cuyo caso reconectamos como struct ciclista *insertar ( struct ciclista * top, struct ciclista * nuevo) Elto 4 struct ciclista *actual = top; /* puntero para moverse por la lista */ nuevo struct ciclista *anterior = ; /*puntero al elemento anterior top = al nuevo "actual" */ /* Búsqueda l punto anterior inserción */ actual while ( (actual!= ) && (actual -> tiempo <= nuevo -> tiempo) ) anterior = actual; actual = actual -> sig; /* Inserción */ if (anterior!= ) /* inserción en medio o final */ anterior -> sig = nuevo; else /* inserción al principio la lista */ top = nuevo; nuevo -> sig = actual; return top; /* vuelve la cabecera la lista */ top Elto 1 Elto 2 Elto 3
2.- Lista Ornada En cualquiera los dos casos: struct ciclista *insertar ( struct ciclista * top, struct ciclista * nuevo) Caso 1: struct ciclista *actual = top; /* puntero para moverse por la lista */ struct ciclista *anterior = ; top Elto 1 Elto 2 Elto 3 Elto 4 /*puntero al elemento anterior al "actual" */ /* Búsqueda l punto inserción */ while ( (actual!= ) && (actual -> anterior tiempo <= nuevo -> tiempo) actual ) nuevo anterior = actual; Caso 2: actual = actual -> sig; /* Inserción */ nuevo if (anterior!= ) /* inserción en medio o final */ anterior -> sig = nuevo; anterior else /* inserción al principio la lista */ top = nuevo; nuevo -> sig = actual; return top; /* vuelve la cabecera la lista */ nuevo -> sig = actual top Elto 1 Elto 2 Elto 3 Elto 4 actual
2.- Lista Ornada struct ciclista *insertar ( struct ciclista * top, struct ciclista * nuevo) struct ciclista *actual = top; /* puntero para moverse por la lista */ struct ciclista *anterior = ; /*puntero al elemento anterior al "actual" */ /* Búsqueda l punto inserción */ while ( (actual!= ) && (actual -> tiempo <= nuevo -> tiempo) ) anterior = actual; actual = actual -> sig; /* Inserción */ if (anterior!= ) /* inserción en medio o final */ anterior -> sig = nuevo; else /* inserción al principio la lista */ top = nuevo; nuevo -> sig = actual; return top; /* vuelve la cabecera la lista */ Para finalizar volvemos la cabecera la lista (Haya ésta cambiado o no)
Recuperación Recuperación elementos elementos 1.- Recorrer la lista completa void listado (struct ciclista * top) struct ciclista *p = top; /* Puntero para recorrer la lista */ while (p) /* Bucle que recorre la lista */ printf("%s %d\n", p -> nombre, p -> tiempo); p = p -> sig; Función que recorre la lista al completo s el primer al último elemento, mostrando los miembros nombre y tiempo.
Recuperación Recuperación elementos elementos 1.- Recorrer la lista completa void listado (struct ciclista * top) struct ciclista *p = top; /* Puntero para recorrer la lista */ while (p) /* Bucle que recorre la lista */ printf("%s %d\n", p -> nombre, p -> tiempo); p = p -> sig; Esta sentencia pu sustituirse en el caso general por cualquier otra secuencia en función los se see hacer con los datos la lista.
Recuperación Recuperación elementos elementos 2.- Búsqueda un elemento concreto struct ciclista * busca (struct ciclista *top, char *c) struct ciclista *p = top; /* Puntero para recorrer la lista */ while (p) if (!strcmp(c, p -> nombre) ) return p; /* vuelve el puntero*/ p = p -> sig; return ; /* no encontrado */ Función que busca el elemento cuyo miembro nombre coincida con el que se le pasa como argumento (char *c). Devuelve un puntero al elemento encontrado, o en caso no encantarlo.
Adicionales Adicionales para para Borrado elementos struct ciclista * borrar (struct ciclista * top, char * c) struct ciclista * p = top, * ant = ; /* Punteros para recorrer lista */ struct ciclista * aux; /* servirá para por liberar memoria */ while(p) if (!strcmp(c, p -> nombre)) /* lo hemos encontrado */ if (ant = = ) /* es el primero */ aux = p -> sig; free(p); Función que borra return un elemento aux; una lista enlazada. Para localizar else /* el el elemento, se a eliminar le pasa el va miembro en medio o al final */ nombre l elemento anta-> eliminar sig = p (char -> sig; *c), y la cabecera la lista free(p); (top) return top; Devuelve un puntero a la nueva cabecera la lista. ant = p; /* avance */ p = p -> sig; /* fin l while */ return top; /* no encontrado o lista vacía */
Adicionales Adicionales para para Borrado elementos struct ciclista * borrar (struct ciclista * top, char * c) struct ciclista * p = top, * ant = ; /* Punteros para recorrer lista */ struct ciclista * aux; /* servirá para por liberar memoria */ while(p) if (!strcmp(c, p -> nombre)) /* lo hemos encontrado */ if (ant = = ) /* es el primero */ aux = p -> sig; free(p); return aux; else /* el elemento a eliminar va en medio o al final */ ant -> sig = p -> sig; free(p); return top; ant = p; /* avance */ p = p -> sig; /* fin l while */ return top; /* no encontrado o lista vacía */ Se finen punteros para recorrer la lista (similar a la función insertar)
Adicionales Adicionales para para Borrado elementos struct ciclista * borrar (struct ciclista * top, char * c) struct ciclista * p = top, * ant = ; /* Punteros para recorrer lista */ struct ciclista * aux; /* servirá para por liberar memoria */ while(p) if (!strcmp(c, p -> nombre)) /* lo hemos encontrado */ if (ant = = ) /* es el primero */ aux = p -> sig; free(p); Recorremos la lista hasta el final return aux; else /* el elemento a eliminar va en medio o al final */ ant -> sig = p -> sig; free(p); return top; ant = p; /* avance */ p = p -> sig; /* fin l while */ return top; /* no encontrado o lista vacía */
Adicionales Adicionales para para Borrado elementos struct ciclista * borrar (struct ciclista * top, char * c) struct ciclista * p = top, * ant = ; /* Punteros para recorrer lista */ struct ciclista * aux; /* servirá para por liberar memoria */ while(p) if (!strcmp(c, p -> nombre)) /* lo hemos encontrado */ if (ant = = ) /* es el primero */ aux = p -> sig; Si el miembro nombre coinci free(p); con el que se le pasa como argumento, entonces el return elemento aux; a borrar está apuntado por actual else /* el elemento a eliminar va en medio o al final */ ant -> sig = p -> sig; free(p); top Elto 1 Elto 2 Elto 3 Elto 4 return top; ant = p; /* avance */ ant p = p -> sig; p /* fin l while */ return top; /* no encontrado o lista vacía */
Adicionales Adicionales para para Borrado elementos struct ciclista * borrar (struct ciclista * top, char * c) struct ciclista * p = top, * ant = ; /* Punteros para recorrer lista */ struct ciclista * aux; /* servirá para por liberar memoria */ while(p) if (!strcmp(c, p -> nombre)) /* lo hemos encontrado */ if (ant = = ) /* es el primero */ aux = p -> sig; free(p); return aux; Dos casos: else /* el elemento a eliminar va en medio o al final */ ant -> sig = p -> sig; 1.- El elemento a borrar free(p); es el primero return top; top Elto 1 Elto 2 Elto 3 Elto 4 ant = p; /* avance */ p ant = p -> sig; p /* fin l while */ return top; /* no encontrado o lista vacía */
Adicionales Adicionales para para Borrado elementos struct ciclista * borrar (struct ciclista * top, char * c) struct ciclista * p = top, * ant = ; /* Punteros para recorrer lista */ struct ciclista * aux; /* servirá para por liberar memoria */ while(p) if (!strcmp(c, p -> nombre)) /* lo hemos encontrado */ if (ant = = ) /* es el primero */ aux = p -> sig; free(p); return aux; else /* el elemento a eliminar va en medio o al final */ ant -> sig = p -> sig; Dos casos: free(p); return top; Liberamos memoria y volvemos la nueva cabecera ant = p; /* avance */ p = topp -> sig; Elto 1 Elto 2 Elto 3 Elto 4 /* fin l while */ return ant top; /* no p encontrado o lista vacía */ aux (nueva cabecera)
Adicionales Adicionales para para Borrado elementos struct ciclista * Dos borrar casos: (struct ciclista * top, char * c) struct ciclista * 2.- p = El top elemento, * ant = a ; borrar /* está Punteros en medio para o recorrer al final lista */ struct ciclista * aux; /* servirá para por liberar memoria */ while(p) Elto 1 top Elto 2 Elto 3 Elto 4 if (!strcmp(c, p -> nombre)) /* lo hemos encontrado */ if (ant = ant = ) p/* es el primero */ aux = p -> sig; free(p); return aux; else /* el elemento a eliminar va en medio o al final */ ant -> sig = p -> sig; free(p); return top; ant = p; /* avance */ p = p -> sig; /* fin l while */ return top; /* no encontrado o lista vacía */
Adicionales Adicionales para para Borrado elementos struct ciclista * Enlazamos borrar (struct saltándonos ciclista * top, el elemento char * c) a borrar y liberamos memoria. Devolvemos la cabecera lista. struct ciclista * p = top, * ant = ; /* Punteros para recorrer lista */ struct ciclista * aux; /* servirá para por liberar memoria */ while(p) Elto 1 top Elto 2 Elto 3 Elto 4 if (!strcmp(c, p -> nombre)) /* lo hemos encontrado */ if (ant = ant = ) /* es el primero p */ aux = p -> sig; free(p); return aux; else /* el elemento a eliminar va en medio o al final */ ant -> sig = p -> sig; free(p); return top; ant = p; /* avance */ p = p -> sig; /* fin l while */ return top; /* no encontrado o lista vacía */
Adicionales Adicionales para para Borrado elementos struct ciclista * borrar (struct ciclista * top, char * c) struct ciclista * p = top, * ant = ; /* Punteros para recorrer lista */ struct ciclista * aux; /* servirá para por liberar memoria */ while(p) if (!strcmp(c, p -> nombre)) /* lo hemos encontrado */ if (ant = = ) /* es el primero */ aux = p -> sig; free(p); return aux; else /* el elemento a eliminar va en medio o al final */ ant -> sig = p -> sig; free(p); Si return llegamos top; al final la lista, significa que no se ha encontrado el elemento a eliminar. ant = p; /* avance Devolvemos */ la cabecera lista. p = p -> sig; /* fin l while */ return top; /* no encontrado o lista vacía */
doblemente Cada elemento contiene dos enlaces con el siguiente y anterior elemento la lista. Conocida la posición un elemento, pomos recorrer la lista en ambas direcciones INICIO LISTA Bloque 1 Bloque 2 Bloque 3 Bloque 4 doblemente doblemente en en C struct direc char nombre[40]; char calle[40]; char ciudad[20]; int codigo; struct direc * sig; struct direc * ante; info; Información l Elemento Enlace con el siguiente elemento y el anterior Por convenio, el fin lista, y el elemento precente al primero se indican como Punteros a la propia estructura DE NUEVO: Cada elemento requiere una reserva dinámica memoria al ser creado (liberar memoria al ser eliminado). La gestión la lista se hace con funciones apropiadas para añadir, insertar, borrar, buscar elementos, etc.
doblemente doblemente doblemente 1.- Lista Desornada struct direc * d_almac_fin(struct direc *top, struct direc * nuevo) struct direc * p = top; /* puntero que recorrerá la lista hasta el final */ if (top = = ) return nuevo ; /* si no existe lista la crea */ while( p -> sig ) p = p -> sig ; /* recorre la lista hasta que p apunte al último */ p -> sig = nuevo; /* enlaza el nuevo elemento al final */ nuevo -> ante = p; /* enlace con el último */ return top; /* vuelve la cabeza */ INICIO LISTA Bloque 1 Bloque 2 Bloque 3 nuevo E. nuevo
doblemente doblemente doblemente 2.- Lista Ornada struct ciclista * dinsertar (struct ciclista * ppio, struct ciclista * nuevo) Estructura Estructura base base para para el el ejemplo ejemplo la la función funcióndinsertar struct ciclista *actual = ppio; /* puntero para moverse por la lista */ struct struct ciclista ciclista *anterior = ; /*puntero al elemento anterior al "actual" */ /* Búsqueda int int l num; num; punto /* /* número número inserción l l ciclista ciclista */ */ */ while ( (actual char char!= nombre[80]; nombre[80]; ) && (/*nombre actual -> tiempo l l ciclista*/ ciclista*/ <= nuevo -> tiempo) ) anterior int inttiempo; tiempo; = actual; /* /* tiempo tiempo en en la la clasificación clasificación */ */ actual struct struct = ciclista ciclista actual -> ** sig; sig; /* /* puntero puntero a siguiente siguiente */ */ /* inserción struct struct */ ciclista ciclista ** ant; ant; /* /* puntero puntero a anterior anterior */ */ if (anterior;!= ; ) anterior -> sig = nuevo; /* inserción en medio o final */ El El objetivo objetivo nuevo es es diseñar diseñar -> ant = la la anterior; función función dinsertar dinsertarpara para crear crear listas listas else ornadas ornadas elementos elementos struct structciclista. ciclista. El El criterio criterio ppio ornación ornación = nuevo; /* será inserción será menor menor al principio a a mayor mayor tiempo tiempo la lista */ clasificación. clasificación. nuevo -> ant = ; nuevo -> sig = actual; if ( actual!= ) actual -> ant = nuevo; return ppio; /* vuelve la cabecera la lista */
doblemente doblemente doblemente 2.- Lista Ornada struct ciclista * dinsertar (struct ciclista * ppio, struct ciclista * nuevo) struct ciclista *actual = ppio; /* puntero para moverse por la lista */ struct ciclista *anterior = ; /*puntero al elemento anterior al "actual" */ /* Búsqueda l punto inserción */ while ( (actual!= ) && ( actual -> tiempo <= nuevo -> tiempo) ) anterior = actual; actual = actual -> sig; /* inserción */ if (anterior!= ) anterior -> sig = nuevo; /* inserción en medio o final */ nuevo -> ant = anterior; else ppio = nuevo; /* inserción al principio la lista */ nuevo -> ant = ; nuevo -> sig = actual; if ( actual!= ) actual -> ant = nuevo; return ppio; /* vuelve la cabecera la lista */
doblemente Borrado elementos struct ciclista * dborrar (struct ciclista * top, char * c) struct ciclista * p = top; while(p) if (!strcmp(c, p->nombre) ) /* lo hemos encontrado */ if ( p -> ant = = ) /* es el primero */ top = p -> sig; if (top) top -> ant = ; /* si el borrado no era único */ free(p);return top; if ( p -> sig = = ) /* si no, es el último */ p -> ant -> sig = ; free (p);return top; else p -> ant -> sig = p -> sig; /* va en medio */ p -> sig -> ant = p -> ant; free(p); return top; /*fin if */ p = p -> sig; /* avance */ /* fin l while */ return top; /* no encontrado o lista vacía */