You are on page 1of 23

UNIVERSIDAD DE EL SALVADOR

EISI

UNIVERSIDAD DE EL SALVADOR FACULTAD DE INGENIERIA Y ARQUITECTURA ESCUELA DE INGENIERIA DE SISTEMAS INFORMATICOS PROGRAMACION II ( SISTEMAS ) GUIA DE LABORATORIO No. 7 LISTAS , LISTAS DOBLEMENTE ENLAZADAS Y LISTAS CIRCULARES Tema: LISTAS
Objetivo: Que el estudiante a travs de la prctica aprenda el funcionamiento y la utilizacin de las estructuras de tipo lista implementada con arreglo y con memoria dinmica. EJEMPLOS DE LISTAS

1. Digite, compile y ejecute el siguiente programa.


/*aplicacion demostrativa de implementacion de listas enlazadas con la utilizacion de un arreglo de nodos vacios */ #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <string.h> #include <iostream.h> #define NumNode 10 #define TRUE 1 #define FALSE 0 struct nodetype { char info[30]; int next; }; int getnode(struct nodetype *,int*); void insafter(int*, char*, struct nodetype *, int* ); void freenode(int p,struct nodetype *,int*); void imprimir_lista(int,struct nodetype *); int ultimo_lista(int, struct nodetype *); int isempty(int); int previo_lista(int,struct nodetype *, char *, int *); char * delafter( int, struct nodetype *, int *); char * remover( int *, struct nodetype *, int * ); char * leer_valor(void);

void main(void) { struct nodetype node[NumNode]; PROGRAMACION II (SISTEMAS) 1 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR int avail=0; /*inicializacion de lista de nodos disponible avail a 0 */

EISI

int i, r, enc, paises=-1, herramientas=-1, alumnos=-1; char pais[30]; char herra[30]; char alum[30]; int salir=FALSE,opcion; /*inicializacion del arreglo de nodos */ for (i=0; i<NumNode-1; i++) { strcpy(node[i].info," "); node[i].next=i+1; } strcpy(node[NumNode-1].info," "); node[NumNode-1].next = -1; /*Menu de opciones*/ while (!salir) { clrscr(); printf("ARREGLO CON 3 LISTAS\n"); printf("1. agregar pais\n"); printf("2. agregar herramienta\n"); printf("3. agregar nombre\n"); printf("4. imprimir listas\n"); printf("5. imprimir VECTOR\n"); printf("6. borrar pais\n"); printf("7. Salir\n\n"); printf("Digite opcin:"); scanf("%d",&opcion); if (opcion == 1) { strcpy(pais, leer_valor()); insafter(&paises,pais,node,&avail); } if (opcion == 2) { strcpy(herra, leer_valor()); insafter(&herramientas, herra,node,&avail); } if (opcion == 3) { strcpy(alum, leer_valor()); insafter(&alumnos,alum,node,&avail); } if (opcion == 4) { printf("\n\nPaises...\n\n"); imprimir_lista(paises,node); printf("Herramientas...\n\n"); imprimir_lista(herramientas,node); printf("Nombres...\n\n"); imprimir_lista(alumnos,node); getch(); } PROGRAMACION II (SISTEMAS) 2 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR if (opcion == 5) { for (i=0;i<NumNode;i++) { printf("Node[%d] = %s %d\n",i,node[i].info,node[i].next); } printf("\n\ninicio de lista PAISES: %d\n",paises); printf("inicio de lista HERRAMIENTAS: %d\n",herramientas); printf("inicio de lista ALUMNOS: %d\n",alumnos); getch(); } if (opcion == 6) { if ( ! ( isempty(paises) ) ) { imprimir_lista(paises, node); printf("Digite nombre de pais a borrar\n"); fflush(stdin); gets(pais); r = previo_lista(paises, node, pais, &enc); if ( enc ) { if ( r != -1 && enc) { strcpy(pais, delafter(r, node, &avail)); printf("El elemento borrado de la lista paises es: %s\n", pais); cout << pais; getch(); } else { if ( paises != -1 && enc) { strcpy(pais, remover(&paises, node, &avail)); printf("El elemento borrado de la lista paises es: %s\n", pais); getch(); } } } else { printf("Revise la lista de paises mostrada. Ese pais no esta en la lista.\n"); getch(); } } /* fin de proceso si pila no esta vacia */ else { printf("La lista esta vacia. No hay elementos a borrar.\n"); getch(); } } if (opcion == 7) { salir = TRUE; } PROGRAMACION II (SISTEMAS) 3

EISI

CICLO I/2009

UNIVERSIDAD DE EL SALVADOR } } /*Recupera el siguiente nodo disponible, y asigna el siguiente node disponible*/ int getnode(struct nodetype * node, int *avail) { int nodo; nodo = *avail; *avail=node[*avail].next; return nodo; } /*Inserta un nodo al final de una lista*/ void insafter( int *lista, char x[30], struct nodetype * node,int* avail) { int nodo, ultimo; if (*avail == -1) { printf("Fallo la insercin, vector lleno\n"); getch(); return; } nodo = getnode(node,avail); strcpy(node[nodo].info, x); if (!isempty(*lista)) // si la lista no esta vaca { ultimo = ultimo_lista(*lista,node); node[ultimo].next = nodo; node[nodo].next=-1; } else // si la lista esta vaca { *lista = nodo; node[nodo].next = -1; } } void freenode(int posicion, struct nodetype * node, int * avail) { node[posicion].next = *avail; strcpy( node[posicion].info, " "); *avail = posicion; } /*Recorre una lista, e imprime cada valor*/ void imprimir_lista(int lista,struct nodetype * node) { int i; i = lista; while ( i != -1 ) { printf("---> %s",node[i].info); printf("\n"); i = node[i].next; } printf("\n\n"); } /*Devuelve la posicin del ultimo nodo en una lista*/ int ultimo_lista(int lista,struct nodetype * node) { PROGRAMACION II (SISTEMAS) 4

EISI

CICLO I/2009

UNIVERSIDAD DE EL SALVADOR int i,next; i=lista; while (node[i].next != -1) { i = node[i].next; } return i; } /*Determina si una lista esta vacia*/ int isempty(int lista) { if (lista == -1) return TRUE; else return FALSE; } /*Devuelve una cadena de caracteres leida*/ char *leer_valor() { char valor[30]; printf("\n\nDigite valor:"); fflush(stdin); gets(valor); return valor; } /* Elimina un nodo despues del nodo apuntado por p en la lista */ char * delafter( int p, struct nodetype * node, int * avail ) { int q; char b[30]; if ( ( p == -1 ) || ( node[p].next == -1 ) ) { printf( " Fallo eliminacion. \n" ); return " "; } q = node[p].next; strcpy( b, node[q].info ); node[p].next = node[q].next; freenode ( q, node, avail ); return b;

EISI

} /*Devuelve la posicin del nodo previo al buscado en una lista. La variable encon devuelve cierto si fue encontrado y falso si no.*/ int previo_lista(int lista,struct nodetype * node, char *valor, int *encon) { int i,prev=-1; i =lista; *encon = FALSE; if ( ! (isempty(lista))) { while ( ! *encon && i != -1 ) { if (strcmp(node[i].info,valor) == 0 ) { PROGRAMACION II (SISTEMAS) 5 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR *encon = TRUE; return prev; }

EISI

prev = i; i = node[i].next; } } return prev; } /* Elimina un nodo al frente de la lista */ char * remover( int *p, struct nodetype * node, int * avail ) { char b[30]; int q; if (*p == -1 ) { printf( " Fallo eliminacion. \n" ); return " "; } q = *p; *p = node[q].next; strcpy( b, node[q].info); freenode ( q, node, avail ); return b; }

2. Modifique el programa anterior para que se pueda eliminar el ltimo elemento en las listas. 3. Digite los diferentes archivos ( .c, .h, .txt ), haga un proyecto, complelo y ejectelo. El problema a solucionar es: Una empresa de reparto de propaganda contrata a sus trabajadores por das. Cada trabajador puede trabajar varios das continuados o alternos. Los datos de los repartidores se almacenan en una lista simplemente enlazada. El programa a desarrollar contempla los siguientes puntos: Crear una estructura de cola para recoger en ella el nmero de la seguridad social de cada repartidor y la entidad anunciada en la propaganda para un nico da de trabajo. Actualizar la lista citada anteriormente (que ya existe con contenido) a partir de los datos de la cola. La informacin de la lista es la siguiente: Nmero de seguridad social, nombre y total de das trabajados. Si el trabajador no est incluido en la lista debe aadirse a la misma de tal manera que siga ordenada.

La implementacin en lenguaje C se har mediante un proyecto constituido por:

PROGRAMACION II (SISTEMAS) 6

CICLO I/2009

UNIVERSIDAD DE EL SALVADOR

EISI

1. Dos archivos de cabecera denominados COLADIM..H, y LISTALIN.H los cuales contendrn las definiciones de las estructuras y los prototipos de las operaciones. 2. Un archivo de implementacin denominado COLADIM.C y LISTALIN.C los cuales contendrn las definiciones de las funciones que soportarn las operaciones 3. Un archivo de aplicacin denominado PROPAGA.C, el cual contiene la lgica. 4. Un archivo de datos denominado GENERAL.TXT, en formato texto el cual contendr los datos con los que funcionar la aplicacin. 5. Un archivo de proyecto denominado APLISTA.PRJ, el cual integrar los archivos de implementacin COLADIM.C, LISTALIN.C y el programa de aplicacin PROPAGA.C.

ARCHIVO COLADIM.H /*Implementacion de cola lineal con memoria dinmica #define CIERTO 1 #define FALSO 0 #define NULO 0 typedef struct{ char SeguroSocial[10]; char Entidad[40]; }TipoDato; struct Nodoq{ TipoDato Info; struct Nodoq * Sgte; }; typedef struct Nodoq * Ptrnodoq; typedef struct{ Ptrnodoq Frente, Final; }TipoCola; void freenode(Ptrnodoq); Ptrnodoq getnode(void); void LimpiarCola(TipoCola *); int ColaVacia(TipoCola ); void Quitar(TipoDato *, TipoCola *); void Poner(TipoDato , TipoCola *);

*/

ARCHIVO COLADIM.C /* COLAS.C */ #include "a:coladim.h" #include <conio.h> #include <stdio.h> void freenode(Ptrnodoq p) { free(p); }

Ptrnodoq getnode(void) { Ptrnodoq p; PROGRAMACION II (SISTEMAS) 7 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR p=(Ptrnodoq)malloc(sizeof(struct Nodoq)); return(p); } void LimpiarCola(TipoCola * pq) { pq->Frente=NULO; pq->Final=NULO; } int ColaVacia(TipoCola q) { return((q.Frente == NULO)? CIERTO: FALSO); } void Poner(TipoDato x , TipoCola * pq) { Ptrnodoq T; T=getnode(); T->Info=x; T->Sgte=NULO; if (ColaVacia(*pq)) pq->Frente=T; else (pq->Final)->Sgte=T; pq->Final=T; } void Quitar(TipoDato * px, TipoCola * pq ) { Ptrnodoq A; if (!ColaVacia(*pq)) { *px=(pq->Frente)->Info; A=pq->Frente; pq->Frente=(pq->Frente)->Sgte; if (pq->Frente==NULO) pq->Final=NULO; freenode(A); } }

EISI

ARCHIVO LISTALIN.H
/*Implementacion de una lista enlazada lineal ordenada #define CIERTO 1 #define FALSO 0 #define NULO 0 typedef struct{ char ISSS[10]; char Nombre[41]; int DiasTrabajados; }TipoInfo; struct Nodo{ TipoInfo Info; struct Nodo * Sgte; }; typedef struct Nodo * ApuntaNodo; void LimpiarLista(ApuntaNodo *); int ListaVacia(ApuntaNodo); PROGRAMACION II (SISTEMAS) 8 */

CICLO I/2009

UNIVERSIDAD DE EL SALVADOR ApuntaNodo PostInsert(TipoInfo, ApuntaNodo ); void InserOrden(TipoInfo , ApuntaNodo *); void Suprimir(TipoInfo * , ApuntaNodo *);

EISI

ARCHIVO LISTALIN.C
/* LISTALIN.C */ #include "a:listalin.h" #include <conio.h> #include <stdio.h> void LimpiarLista(ApuntaNodo * pl) { *pl=NULO; } int ListaVacia(ApuntaNodo l) { return((l == NULO)? CIERTO: FALSO); } ApuntaNodo PostInsert(TipoInfo x, ApuntaNodo l) { ApuntaNodo T; T=NULO; if (!ListaVacia(l)){ while ((strcmp(x.ISSS, l->Info.ISSS)>=0) && (l->Sgte!= NULO)){ T=l; l=l->Sgte; } if (strcmp(x.ISSS,l->Info.ISSS)>=0) T=l; } return(T); } void InserOrden(TipoInfo x , ApuntaNodo * pl) { ApuntaNodo A,N; N=(ApuntaNodo) malloc (sizeof(struct Nodo)); N->Info=x; N->Sgte=NULO; if (ListaVacia(*pl)) *pl=N; else{ A=PostInsert(x,*pl); if (A==NULO){ N->Sgte=*pl; *pl=N; } else{ N->Sgte=A->Sgte; A->Sgte=N; } } } void Suprimir(TipoInfo * px, ApuntaNodo *pl) { ApuntaNodo A; PROGRAMACION II (SISTEMAS) 9 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR if (! ListaVacia(*pl)){ A=*pl; *px=A->Info; *pl=A->Sgte; free(A); } }

EISI

ARCHIVO PROPAGA.C
/*Nombre:PROPAGA*/ #include <conio.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include "a:coladim.h" #include "a:listalin.h" main() { /* Variable */ TipoCola DatosDiarios; ApuntaNodo DatosGenerales, Aux; TipoDato DatoCola; TipoInfo DatoLista;

FILE * arch; /* Inicializaciones */ LimpiarLista(&DatosGenerales); LimpiarCola(&DatosDiarios); arch=fopen("a:General.txt","r"); /*Creacin de la lista*/ while (!feof(arch)) { fscanf(arch, "%s \n", DatoLista.ISSS); fscanf(arch, "%s \n", DatoLista.Nombre); fscanf(arch, "%d \n", &DatoLista.DiasTrabajados); InserOrden(DatoLista,&DatosGenerales); } fclose(arch); /* Registro de datos diarios */ clrscr(); printf("\nDigite -1 en Numero de Seguro Social para terminar\n"); printf("Numero de Seguro Social:"); fflush(stdin); scanf("%s",DatoCola.SeguroSocial); while (strcmp(DatoCola.SeguroSocial,"-1")) { fflush(stdin); printf("Entidad:"); scanf("%s",DatoCola.Entidad); Poner(DatoCola,&DatosDiarios); printf("\nDigite -1 en Numero de Seguro Social para terminar\n"); printf("Numero de Seguro Social:"); scanf("%s",DatoCola.SeguroSocial); } /* Actualizar Lista */ while (!ColaVacia(DatosDiarios)) { PROGRAMACION II (SISTEMAS) 10 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR Quitar(&DatoCola,&DatosDiarios); /*Busqueda de empleado*/ Aux=DatosGenerales; while((strcmp(Aux->Info.ISSS,DatoCola.SeguroSocial)<0) && (Aux->Sgte != NULO) ) Aux=Aux->Sgte; /*Actualiza o Agrega*/ if (!strcmp(Aux->Info.ISSS,DatoCola.SeguroSocial)) Aux->Info.DiasTrabajados++; else {strcpy(DatoLista.ISSS,DatoCola.SeguroSocial); DatoLista.DiasTrabajados=1; clrscr(); printf("\nAgregando un Nuevo Empleado\n"); printf("Numero Seguro Social:%s\n",DatoLista.ISSS); printf("Nombre:"); scanf("%s",DatoLista.Nombre); InserOrden(DatoLista,&DatosGenerales); } } /*Mostrar el contenido de la Lista*/ clrscr(); printf("\nListado General de Empleados\n"); Aux=DatosGenerales; while(Aux!=NULO){ printf("Numero Seguro Social:%s\n",Aux->Info.ISSS); printf("Nombre:%s\n",Aux->Info.Nombre); printf("Dias Trabajados:%d\n\n",Aux->Info.DiasTrabajados); Aux=Aux->Sgte; } printf("<ENTER> para continuar.....\n\n"); getch(); /*Actualizando Archivos de texto*/ arch=fopen("a:General.txt","w"); printf("Guardando en Archivo"); while(!ListaVacia(DatosGenerales)){ Suprimir(&DatoLista,&DatosGenerales); fprintf(arch,"%s\n",DatoLista.ISSS); fprintf(arch,"%s\n",DatoLista.Nombre); fprintf(arch,"%d\n",DatoLista.DiasTrabajados); } fclose(arch); return(0); }/* main */

EISI

ARCHIVO ORIGINAL GENERAL.TXT


098765432 Luis 1 123456787 Mario 1 123456789 Silvia PROGRAMACION II (SISTEMAS) 11 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR 5 987654321 Marta 4

EISI

CORRIDA DEL PROGRAMA


Listado General de Empleados Numero Seguro Social: 098765432 Nombre: Luis Dias Trabajados: 1 Numero Seguro Social: 123456787 Nombre: Mario Dias Trabajados: 1 Numero Seguro Social: 123456789 Nombre: Silvia Dias Trabajados: 6 Numero Seguro Social: 567891234 Nombre: Guadalupe Dias Trabajados: 1 Numero Seguro Social: 987654321 Nombre: Marta Dias Trabajados: 4

ARCHIVO FINAL GENERAL.TXT


098765432 Luis 1 123456787 Mario 1 123456789 Silvia 6 567891234 Guadalupe 1 987654321 Marta 4

EJERCICIOS DE LISTAS 1. Escriba una funcin para ejecutar cada una de las siguientes operaciones, utilizar memoria dinmica: a. Concatenar dos listas. b. Invertir una lista, de manera que el ltimo elemento se convierta en el primero y as sucesivamente. c. Suprimir el ensimo elemento de una lista. d. Combinar dos listas ordenadas en una sola lista ordenada.
PROGRAMACION II (SISTEMAS) 12 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR

EISI

e. Suprimir cada segundo elemento de una lista. f. Colocar los elementos de una lista en orden creciente. g. Retornar la cantidad de elementos en una lista. Hacer un programa principal que ofrezca todas estas opciones, adems de las operaciones bsicas de una lista. 2. Realizar el ejercicio anterior pero implementarlo usando memoria esttica (arreglo). 3. Escriba funciones para realizar cada una de las operaciones del ejercicio 4, suponiendo que cada lista contiene un nodo de encabezado que incluye el nmero de elementos en la lista. Hacer un programa para probar la funcionalidad de las funciones.

Tema: LISTAS DOBLEMENTE ENLAZADAS Objetivo: Que el estudiante a travs de la prctica aprenda el funcionamiento y la utilizacin de la estructura lista doblemente enlazada.

1. Digite, compile y ejecute el siguiente programa. /* El siguiente programa ofrece diferentes opciones, a travs de un men, de operaciones con listas doblemente enlazadas: insertar un nodo, buscar, borrar nodo, imprimir ascendente, imprimir descendente. */ #include <stdlib.h> #include <stdio.h> #include <conio.h> #define ASCENDENTE 1 #define DESCENDENTE 0 #define TRUE 1 #define FALSE 0 typedef struct _nodo { int valor; struct _nodo *siguiente; struct _nodo *anterior; } tipoNodo; typedef tipoNodo *pNodo; typedef tipoNodo *Lista; /* Funciones con listas: */ void Insertar(Lista *l, int v); void Borrar(Lista *l, int v); pNodo getnodo(void); void BorrarLista(Lista *); void MostrarLista(Lista l, int orden);
PROGRAMACION II (SISTEMAS) 13 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR

EISI

pNodo buscar_nodo( Lista, int, int *); void menu(void); void main(void) { Lista lista = NULL; pNodo p; int opcion, v, enc, cont=TRUE; clrscr(); while ( cont ) { menu(); printf("Digite una opcion:\n "); scanf("%d", &opcion); switch(opcion) { case 1: /*Insertar un elemento a la lista doblemente enlazada */ printf("Digite el valor a insertar en la lista: \n"); scanf("%d", &v); Insertar(&lista, v); break; case 2: /* Borrar un elemento de la lista doblemente enlazada*/ MostrarLista(lista, ASCENDENTE); printf("Digite el valor a borrar de la lista: \n"); scanf("%d", &v); Borrar(&lista, v); break; case 3: /* Buscar un elemento en la lista doblemente enlazada */ printf("Digite el valor a buscar en la lista. \n"); scanf("%d", &v); buscar_nodo(lista, v, &enc); if (enc) printf("El valor si existe en la lista.\n"); else printf("El valor no esta en la lista.\n"); break; case 4: /*Imprimir la lista en forma ASCENDENTE */ MostrarLista(lista, ASCENDENTE); break; case 5: /*Imprimir la lista en forma DESCENDENTE */ MostrarLista(lista, DESCENDENTE); break; case 6: cont = FALSE; } /* fin del switch */ } /*fin del while */ /* Liberar toda la memoria utilizada */ BorrarLista(&lista); getch(); }
PROGRAMACION II (SISTEMAS) 14 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR

EISI

void Insertar(Lista *lista, int v) { pNodo nuevo, actual; /* pedir un nodo nuevo */ nuevo = getnodo(); nuevo->valor = v; /* Colocamos actual en la primera posicin de la lista */ actual = *lista; if(actual) while(actual->anterior) actual = actual->anterior; /* Si la lista est vaca o el primer miembro es mayor que el nuevo*/ if(!actual || actual->valor > v) { /* Aadimos la lista a continuacin del nuevo nodo */ nuevo->siguiente = actual; nuevo->anterior = NULL; if(actual) actual->anterior = nuevo; if(!*lista) *lista = nuevo; } else { /* Avanzamos hasta el ltimo elemento o hasta que el siguiente tenga un valor mayor que v */ while(actual->siguiente && actual->siguiente->valor <= v) actual = actual->siguiente; /* Insertamos el nuevo nodo despus del nodo anterior */ nuevo->siguiente = actual->siguiente; actual->siguiente = nuevo; nuevo->anterior = actual; if(nuevo->siguiente) nuevo->siguiente->anterior = nuevo; } } void Borrar(Lista *lista, int v) { pNodo nodo; /* Buscar el nodo de valor v */ nodo = *lista; while(nodo && nodo->valor < v) nodo = nodo->siguiente; while(nodo && nodo->valor > v) nodo = nodo->anterior; /* El valor v no est en la lista */ if(!nodo || nodo->valor != v) return; /* Borrar el nodo */ /* Si lista apunta al nodo que queremos borrar, apuntar a otro */ if(nodo == *lista) if(nodo->anterior) *lista = nodo->anterior; else *lista = nodo->siguiente;
PROGRAMACION II (SISTEMAS) 15 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR

EISI

if(nodo->anterior) /* no es el primer elemento */ nodo->anterior->siguiente = nodo->siguiente; if(nodo->siguiente) /* no es el ltimo nodo */ nodo->siguiente->anterior = nodo->anterior; free(nodo); } void BorrarLista(Lista *lista) { pNodo nodo, actual; actual = *lista; while(actual->anterior) actual = actual->anterior; while(actual) { nodo = actual; actual = actual->siguiente; free(nodo); } *lista = NULL; } void MostrarLista(Lista lista, int orden) { pNodo nodo = lista; if(!lista) printf("Lista vaca"); nodo = lista; if(orden == ASCENDENTE) { while(nodo->anterior) nodo = nodo->anterior; printf("Orden ascendente: "); while(nodo) { printf("%d -> ", nodo->valor); nodo = nodo->siguiente; } } else { while(nodo->siguiente) nodo = nodo->siguiente; printf("Orden descendente: "); while(nodo) { printf("%d -> ", nodo->valor); nodo = nodo->anterior; } } printf("\n"); } pNodo getnodo(void) {
PROGRAMACION II (SISTEMAS) 16 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR

EISI

pNodo nuevo;

/* Crear un nodo nuevo */ nuevo = (pNodo)malloc(sizeof(tipoNodo)); return nuevo; } pNodo buscar_nodo( Lista lista, int v, int *enc ) { pNodo nodo; /* Buscar el nodo de valor v */ nodo = lista; while(nodo && nodo->valor < v) nodo = nodo->siguiente; while(nodo && nodo->valor > v) nodo = nodo->anterior; /* El valor v no est en la lista */ if(!nodo || nodo->valor != v) *enc = FALSE; /* devolver a travs de enc si v fue encontrado en la lista */ else *enc = TRUE ; /* devolver el apuntador al nodo */ return nodo; } void menu(void) { printf("\n------------------------------------------------\n"); printf("----------------- M E N U ----------------------\n"); printf("------------------------------------------------\n"); printf("1. Introducir un elemento en la lista.\n"); printf("2. Borrar un elemento de la lista.\n"); printf("3. Buscar un elemento en la lista.\n"); printf("4. Imprimir la lista en forma ASCENDENTE\n"); printf("5. Imprimir la lista en forma DESCENDENTE\n"); printf("6. Salir. \n"); } 2. Modificar el programa anterior para que implemente un nodo de encabezado en la lista doblemente enlazada, en el cual debe estar el nmero de nodos de la lista.

EJERCICIOS DE LISTAS DOBLEMENTE ENLAZADAS 1. Una tienda de artculos deportivos desea almacenar en una lista doblemente enlazada, con un nico elemento por producto, la siguiente informacin sobre las ventas realizadas: cdigo del artculo, cantidad y precio. Desarrollar un programa que permita tanto la creacin de la lista como su actualizacin al realizarse nuevas ventas o devoluciones de un determinado producto.
PROGRAMACION II (SISTEMAS) 17 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR

EISI

2. Escribir un programa que divide una lista doblemente enlazada determinada en dos listas doblemente enlazadas independientes. El primer nodo de la lista principal es PRIMERO y la variable PARTIR es la direccin del nodo que se convierte en el primero de los nodos de la segunda lista doblemente enlazada resultante. 3. Dadas dos listas doblemente enlazadas, cuyos nodos frontales se indican con los apuntadores LISTA1 y LISTA2, respectivamente, realizar un programa que una ambas listas. El nodo frontal de la lista nueva se indicar por LISTA3. 4. Hacer una funcin que cambie el campo INFO del n-simo nodo de una lista doblemente enlazada por un valor dado de x. Probar la funcin en un programa. 5. Escriba un programa en C para convertir una cadena prefija a posfija, utilizando una lista doblemente enlazada. 6. Escriba la rutina reduce en C y que acepte una cadena interfija y forme una cadena interfija equivalente quitando todos los parntesis superfluos, utilizando una lista doblemente enlazada. 7. Utilizar una lista doblemente enlazada para controlar una lista de pasajeros de una lnea area. El programa principal debe ser controlado por men y permitir al usuario visualizar los datos de un pasajero determinado, insertar un nodo (siempre por el final), eliminar un pasajero de la lista. A la lista se accede por un puntero al primer nodo y otro al ltimo. 8. Para representar un entero largo, de ms de 30 dgitos, utilizar una lista circular teniendo el campo dato de cada nodo un dgito del entero largo. Escribir un programa en el que se introduzcan dos enteros largos y se obtenga su suma. 9. Un vector disperso es aquel que tiene muchos elementos que son cero. Escribir un programa que permita representar mediante listas doblemente enlazadas un vector disperso. Los nodos de la lista son los elementos de la lista distintos de cero; en cada nodo se representa el valor del elemento y el ndice (posicin del vector). El programa ha de realizar las operaciones: sumar dos vectores de igual dimensin, y hallar el producto escalar.

PROGRAMACION II (SISTEMAS) 18

CICLO I/2009

UNIVERSIDAD DE EL SALVADOR

EISI

Tema: LISTAS CIRCULARES Objetivo: Que el estudiante a travs de la prctica aprenda el funcionamiento y la utilizacin de la estructura lista circulares.

Digite, compile y ejecute el siguiente programa. #include <stdio.h> #include <conio.h> #include <stdlib.h> /* Aplicacion de listas circulares con nodos de encabezado. El Hw solo permite enteros de una longitud maxima especifica. Suponga que queremos representar enteros positivos de longitud arbitraria y escribir una funcion que retorne la suma de esos dos enteros. Para agregar dos enteros, se recorren sus digitos de derecha a izquierda y se suman los digitos correspondientes y un posible acarreo de la suma de digitos anterior. */ // estructura de los nodos struct node { long int info; struct node *next; }; typedef struct node *NODEPTR; // el nodo de encabezado de la lista circular se distingue por un valor -1. NODEPTR addint ( NODEPTR , NODEPTR ); NODEPTR getnode ( void ); void insert ( NODEPTR *, long int ); void imprimir( NODEPTR ); void insafter (NODEPTR, long int ); void main ( void ) { long int a[10]={0}, a1, a2, a3, a4; int i,dig; NODEPTR r = NULL,lista = NULL, lis2=NULL; printf( "Este es un programa que puede representar enteros bastante largos. "); printf( "Se le pide digite el numero de 5 en 5 dgitos, seguidos de un <enter>"); printf(" Ejemplo: el numero a digitar es: 459763497210698463 \n"); printf("Digite: 459 <enter> 76349 <enter> 72106 <enter> 98463 <enter>\n"); printf("Capacidad maxima: 50 digitos \n"); printf("Cuantos grupos de 5 digitos o menos va a digitar: (maximo: 10) "); scanf("%d", &dig); printf("arreglo:"); for (i=0; i<10; i++) printf("%d", a[i]);
PROGRAMACION II (SISTEMAS) 19 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR

EISI

printf("\n"); for ( i=0; i<dig; i++) { fflush(stdin); scanf("%D",&a[i]); } for ( i=0; i < dig; i++) insert(&lista, a[i]); imprimir(lista); printf("Probemos ahora la suma de dos listas: \n"); printf("Sumaremos a su numero, el numero: 45976349721069846354\n"); a1 = 45976; a2 = 34972; a3 = 10698; a4 = 46354; insert(&lis2, a1); insert(&lis2, a2); insert(&lis2, a3); insert(&lis2, a4); r= addint(lista, lis2); printf("La suma de los 2 numeros es: "); imprimir(r); printf("\n"); getch(); } NODEPTR getnode(void) { NODEPTR p; p = (NODEPTR) malloc ( sizeof ( struct node )); return p; } /* inserta un nodo al inicio de la lista circular */ void insert ( NODEPTR *pq, long int x) { NODEPTR p, aux; p = getnode(); p->info = x; if ( *pq == NULL ) { aux = getnode(); aux->info = -1; aux->next = p; *pq = aux; p->next = aux; } else { p->next = (*pq)->next; (*pq)->next = p; } /*fin del else */
PROGRAMACION II (SISTEMAS) 20 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR

EISI

} /*fin del insert */ NODEPTR addint ( NODEPTR p, NODEPTR q) { long int hunthou = 100000L; long int carry, number, total; NODEPTR s; /*establecer p y q para los nodos despues de los encabezados */ p = p->next; q = q->next; /*preparar un nodo de encabezado para la suma */ s = getnode(); s->info = -1; s->next = s; /*inicialmente no hay acarreo */ carry = 0; while ( p->info != -1 && q->info != -1 ) { /*sumar el campo info de los dos nodos y el acarreo previo */ total = p->info + q->info + carry; /*determinar los 5 digitos de orden inferior de la suma e insertarlos en la lista */ number = total % hunthou; insafter(s, number); /*avanzar los recorridos */ s = s->next; p = p->next; q = q->next; /*determinar si hay acarreo */ carry = total / hunthou; } /*fin de while */ /*en este punto pueden quedar nodos en una de las dos listas de ingreso*/ while (p->info != -1) { total = p->info + carry; number = total % hunthou;

insafter(s, number); carry = total / hunthou; s = s->next; p = p->next; } /*fin de while */


PROGRAMACION II (SISTEMAS) 21 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR

EISI

while (q->info != -1) { total = q->info + carry; number = total % hunthou; insafter(s, number); carry = total / hunthou; s = s->next; q = q->next; } /*fin de while */ /*comprobar si hay un acarreo extra de los primeros cinco dgitos*/ if (carry == 1) { insafter(s, carry); s = s->next; } /*fin de if */ /* s apunta al ultimo nodo en la suma. s->next apunta al encabezado de la lista de suma. */ return ( s->next ); } /*fin de addint */ /*inserta un nodo despus del nodo apuntado por p */ void insafter (NODEPTR p, long int x) { NODEPTR q; q = getnode(); if ( p == NULL ) { p=getnode(); p->info = -1; p->next = q; q->info = x; q->next = p; } else { q->info = x; q->next = p->next; p->next = q; } } /*fin de insafter */ void imprimir( NODEPTR L ) { NODEPTR L1; long int B[10]={0}; int i=0, k; if (L->info == -1) { L1=L->next; while ( L1->info != -1 )
PROGRAMACION II (SISTEMAS) 22 CICLO I/2009

UNIVERSIDAD DE EL SALVADOR

EISI

{ B[i++]=L1->info; L1 = L1->next; } k=i-1; for ( ; k>=0; k--) printf("%d", B[k]); printf("\n"); } }

PROGRAMACION II (SISTEMAS) 23

CICLO I/2009