Documentos de Académico
Documentos de Profesional
Documentos de Cultura
cdigo
64 Kb
En la PILA son colocados los datos automticos que se crean y se liberan a medida que se ejecuta el programa. Por ejemplo, la pila crece con cada entrada en una funcin para crear espacio para todas las variables locales necesarias durante la duracin de la funcin, decrece a cada salida. El MONTN o heap es el rea de memoria libre que es gestionada por las funciones de asignacin dinmica malloc() y free(). - La funcin malloc() asigna memoria en tiempo de ejecucin y devuelve un puntero void al comienzo de esa memoria. - La funcin free() devuelve al montn memoria previamente asignada para que pueda ser reutilizada. Los prototipos de estas funciones son: void *malloc (unsigned int); void free (void *p); Ambas funciones usan el archivo de cabecera <stdlib.h> <alloc.h>. El nico argumento de malloc es de tipo unsigned int, lo que significa que esta funcin permite reservar espacios cuya longitud no sobrepase los 64 K. Si no hay suficiente memoria libre para satisfacer la peticin malloc(), devuelve un nulo. Como el resultado devuelto por malloc es un puntero genrico (void), podr por tanto ser convertido implcitamente (sin casting, sin obligarle a) en un puntero de cualquier tipo, sin embargo, es conveniente utilizar la conversin para saber el tipo de puntero con el que estamos trabajando. Es importante llamar a free() slo con un puntero vlido previamente asignado. De otro modo puede producir un fallo en el programa. Ej.- char *p; p=malloc(25); <=> p=(char*)malloc(25); casting a puntero char Despus de la asignacin, p apunta al primero de los 25 bytes libres de memoria.
E. dinmicas 1
Ej.- int *ptr; ptr=(int*) malloc (50 *sizeof(int)); Dispone espacio para 50 enteros, el uso de sizeof es para asegurar la portabilidad. Como el montn no es infinito, siempre que se asigne memoria, es necesario comprobar antes de usar el puntero el valor devuelto por malloc(), para asegurar que no es nulo.
Ej.- char *p; p=malloc(25); if (p==NULL) { printf(\n No hay memoria suficiente); exit(1); }
(a)
(b)
E. dinmicas 2
Para poder realizar la implementacin del tipo lista enlazada en C es necesaria la utilizacin de estructuras autorreferenciadas, es decir, estructuras en las que uno de sus miembros es un puntero que referencia a la misma estructura. La componente de una lista quedara: Ej.- struct nodo { struct nombre estructura informacin; struct nodo *enlace }; Ej.- struct componente { tipo_elemento elemento; struct componente*enlace; }; La lista completa sera un puntero a una estructura de este tipo: typedef struct componente *tipo_lista mientras que la lista vaca es un puntero a NULL. tipo lista listavacia; listavacia= NULL;
E. dinmicas 3
#include <stdio.h> #include <stdlib.h> #include <conio.h> typedef struct nodo { int dato; struct nodo *enlace; } LISTA; void mostrar_lista(LISTA *ptr); void insertar(LISTA **ptr, int elemento); main() { LISTA *n1 = NULL; int elemento; clrscr(); do { printf("\nIntroduzca un nmero entero o 0 para fin: "); scanf("%d",&elemento); if(elemento != 0) insertar(&n1, elemento); } while(elemento != 0); printf("\nLa nueva lista enlazada es: "); mostrar_lista(n1); } void mostrar_lista(LISTA *ptr) { while(ptr != NULL) { printf("%d",ptr->dato); ptr = ptr->enlace; } printf("\n"); } void insertar(LISTA **ptr, int elemento) { LISTA *p1, *p2; p1 = *ptr; if(p1 == NULL) /* la lista est vaca */ {
E. dinmicas 4
p1 = malloc(sizeof(LISTA)); if (p1 != NULL) { p1->dato = elemento; p1->enlace = NULL; *ptr = p1; } } else /* la lista contiene algn elemento */ { while(p1->enlace != NULL) p1 = p1->enlace; /* recorro hasta llegar al final donde inserto */ p2 = malloc(sizeof(LISTA)); if(p2 != NULL) { p2->dato = elemento; p2->enlace = NULL; p1->enlace = p2; } } }
salida: Introduzca un nmero entero o 0 para fin: 3 Introduzca un nmero entero o 0 para fin: 7 Introduzca un nmero entero o 0 para fin: 8 Introduzca un nmero entero o 0 para fin: 9 Introduzca un nmero entero o 0 para fin: 0 La nueva lista enlazada es: 3789
Ejemplo2: crear una lista con tres caracteres por asignacin e insertar un carcter al principio y otro al final.
E. dinmicas 5
char dato; struct nodo *enlace; } LISTA; void mostrar_lista(LISTA *ptr); void insertar_al_principio(LISTA **ptr, char item); void insertar_al_final(LISTA *ptr, char item); main() { LISTA *n1, *n2, *n3; clrscr(); n1 = malloc(sizeof(LISTA)); n2 = malloc(sizeof(LISTA)); n3 = malloc(sizeof(LISTA)); printf(\n LISTA ocupa %d octetos ,sizeof(LISTA)); printf("\n &n1 = %u",&n1); printf("\n &n2 = %u",&n2); printf("\n &n3 = %u",&n3); printf("\n n1 = %u",n1); printf("\n n2 = %u",n2); printf("\n n3 = %u",n3); n1->dato = 'c'; n1->enlace = n2; n2->dato = 'a'; n2->enlace = n3; n3->dato = 't'; n3->enlace = NULL; printf("\n La lista enlazada es como sigue: "); mostrar_lista(n1); insertar_al_principio(&n1,'s'); printf("\n n1 = %u",n1); printf("\n La nueva lista enlazada es: "); mostrar_lista(n1); insertar_al_final(n1,'m'); printf("\n La nueva lista enlazada es: "); mostrar_lista(n1); }
E. dinmicas 6
printf("\n"); } void insertar_al_principio(LISTA **ptr, char item) { LISTA *new; new = malloc(sizeof(LISTA)); printf("\n &new = %u",&new); printf("\n new =%u",new); if(new != NULL) { new->dato = item; new->enlace = *ptr; *ptr = new; } } void insertar_al_final(LISTA *ptr, char item) { LISTA *new; while(ptr->enlace != NULL) ptr = ptr->enlace; new = malloc(sizeof(LISTA)); printf("\n new =%u",new); if(new != NULL) { ptr->enlace = new; new->dato = item; new->enlace = NULL; } }
salida: LISTA ocupa 5 octetos &n1 = 6553088 &n2 = 6553084 &n3 = 6553080 n1 = 6693540 n2 = 6693556 n3 = 6693572 La lista enlazada es como sigue: cat &new = 6553056 new =6693588 n1 = 6693588 La nueva lista enlazada es: scat new =6693604 La nueva lista enlazada es: scatm
E. dinmicas 7
Ejercicio1: Bsqueda de un elemento en una lista enlazada, introduciendo el elemento a buscar por teclado.
#include <stdio.h> #include <stdlib.h> typedef struct nodo { char dato; struct nodo *enlace; } LISTA; void mostrar_lista(LISTA *ptr); int buscar_en_lista(LISTA *ptr, char item); main() { LISTA *n1, *n2, *n3, *n4; char item; int encontrado; n1 = malloc(sizeof(LISTA)); n2 = malloc(sizeof(LISTA)); n3 = malloc(sizeof(LISTA)); n4 = malloc(sizeof(LISTA)); n1->dato = 'a'; n1->enlace = n2; n2->dato = 'b'; n2->enlace = n3; n3->dato = 'c'; n3->enlace = n4; n4->dato = 'd'; n4->enlace = NULL; printf("La lista enlazada es como sigue: "); mostrar_lista(n1); printf("Introduzca un caracter a buscar en la lista: "); item = getchar(); encontrado = buscar_en_lista(n1,item); printf("\nEl caracter %c ",item); if (encontrado) printf("sido encontrado en la lista: "); else printf("no ha sido encontrado en la lista: "); mostrar_lista(n1); } void mostrar_lista(LISTA *ptr) {
E. dinmicas 8
while(ptr != NULL) { printf("%c",ptr->dato); ptr = ptr->enlace; } printf("\n"); } int buscar_en_lista(LISTA *ptr, char item) { if(ptr == NULL) return(0); else { do { if(ptr->dato == item) return(1); ptr = ptr->enlace; } while(ptr != NULL); return(0); } }
EJERCICIO 2: Llenar una lista enlazada con nmeros enteros (ordenados de menor a mayor) hasta introducir un cero e inserte un numero entero en la posicin correcta de la lista enlazada.
#include <stdio.h> #include <stdlib.h> #include <conio.h> typedef struct nodo { int dato; struct nodo *enlace; } LISTA; void mostrar_lista(LISTA *ptr); void insertar(LISTA **ptr, int elemento); void insertar_ordenado(LISTA **ptr,int item); main() { LISTA *n1 = NULL;
E. dinmicas 9
int elemento; clrscr(); do { printf("\nIntroduzca un nmero entero o 0 para fin: "); scanf("%d",&elemento); if(elemento != 0) insertar(&n1, elemento); } while(elemento != 0); printf("\nLa nueva lista enlazada es: "); mostrar_lista(n1); printf("\n introduce elemento a insertar:"); scanf("%d",&elemento); insertar_ordenado(&n1,elemento); printf("\n lanueva lista despues de insertar es:"); mostrar_lista(n1); getchar(); getchar(); } void mostrar_lista(LISTA *ptr) { while(ptr != NULL) { printf("%d",ptr->dato); ptr = ptr->enlace; } printf("\n"); } void insertar(LISTA **ptr, int elemento) { LISTA *p1, *p2; p1 = *ptr; if(p1 == NULL) { p1 = malloc(sizeof(LISTA)); if (p1 != NULL) { p1->dato = elemento; p1->enlace = NULL; *ptr = p1; } } else {
E. dinmicas 10
while(p1->enlace != NULL) p1 = p1->enlace; p2 = malloc(sizeof(LISTA)); if(p2 != NULL) { p2->dato = elemento; p2->enlace = NULL; p1->enlace = p2; } } } void insertar_ordenado(LISTA**ptr,int item) { LISTA *nuevo,*aux,*precede; int encontrado=0; aux=*ptr; while(!encontrado && aux!=NULL) { if (item < aux->dato ) encontrado=1; else { precede=aux; aux=aux->enlace; } } nuevo = malloc(sizeof(LISTA)); if (nuevo != NULL) nuevo->dato=item; if (*ptr==aux) /*dato se inserta al principio */ { nuevo->enlace=*ptr; *ptr=nuevo; } else { precede->enlace=nuevo; nuevo->enlace=aux; } }
salida: Introduzca un nmero entero o 0 para fin: 2 Introduzca un nmero entero o 0 para fin: 4 Introduzca un nmero entero o 0 para fin: 7
E. dinmicas 11
Introduzca un nmero entero o 0 para fin: 9 Introduzca un nmero entero o 0 para fin: 0 La nueva lista enlazada es: 2479 introduce elemento a insertar:5 la nueva lista despues de insertar es:24579
2.2.- PILAS
Una pila se define como una lista enlazada de elementos en la cual un elemento slo puede ser aadido o eliminado por un extremo llamado CIMA. Las pilas se conocen como estructuras LIFO (Last In First Out, ltimo en entrar, primero en salir). Como una pila es una estructura dinmica de datos, vara conforme se quiten o aadan elementos. Es necesario definir dos operaciones relacionadas con la insercin de elementos: Introducir o meter datos en la pila (push) que es la operacin que aade un elemento por la cima de la pila, modificando a la vez la direccin de sta (cima). Extraer o sacar datos de la pila (pop) que es la operacin que elimina el elemento de la cima generando un nuevo valor de sta. Antes de meter algn elemento, hay que generar dicha pila, es decir, necesitamos otra operacin que cree la pila vaca. Antes de sacar un elemento se debe comprobar si la pila est vaca o no.
PILA
Cima a
PILA NULL
PILA
Cima c
NULL
/* Implementacin de una pila de caracteres */ #include <stdio.h> #include <conio.h> #include <stdlib.h> typedef struct nodo{ char dato; struct nodo *enlace; }PILA; void mostrar(PILA *ptr);
E. dinmicas 12
int vacia(PILA *ptr); void introducir(PILA ** ptr, char item); char extraer(PILA**ptr); main () { PILA *pila=NULL; clrscr(); introducir(&pila,'a'); introducir(&pila,'b'); introducir(&pila,'c'); printf("La pila es como sigue:"); mostrar(pila); printf ("\nEl primer elemento obtenido es %c\n",extraer(&pila)); printf ("\nEl segundo elemento obtenido es %c\n",extraer(&pila)); printf ("\nEl tercer elemento obtenido es %c\n",extraer(&pila)); extraer(&pila); getche(); } void mostrar(PILA *ptr) { while(ptr!=NULL) { printf("%c",ptr->dato); ptr=ptr->enlace; } printf("\n"); } int vacia(PILA *ptr) { if (ptr==NULL) return(1); else return(0); } void introducir(PILA **ptr,char item) { PILA *p; if (vacia(*ptr)) { p=(PILA *)malloc(sizeof(PILA)); if(p!=NULL) { p->dato=item; p->enlace=NULL; *ptr=p; } }
E. dinmicas 13
else { p=(PILA *)malloc(sizeof(PILA)); if(p!=NULL) { p->dato=item; p->enlace=*ptr; *ptr=p; } } } char extraer(PILA**ptr) { PILA *p1; p1=*ptr; char item; if(vacia(p1)) { printf("Error! La pila esta vacia\n"); } else { item=p1->dato; *ptr=p1->enlace; free(p1); return(item); } }
2.3.- COLAS Una cola se define como una lista enlazada de elementos en la que las eliminaciones se producen por un extremo llamado FRENTE o CABEZA y las inserciones por el otro extremo llamado FINAL O COLA Se la denomina tambin estructura FIFO (First In First Out, primero en entrar, primero en salir). Una cola puede tambin implementarse como una lista doblemente enlazada. Se utilizan dos punteros para acceder a la cola. En este caso, los nodos que constituyen la lista enlazada de la cola contienen dos campos de enlace. Un campo de enlace se utiliza para apuntar al siguiente nodo de la lista y el otro para apuntar al nodo anterior de la lista. La estructura en C sera: typedef struct nodo { char dato; struct nodo*enlace_sig; struct nodo*enlace_ant; }COLA;
cabeza
E. dinmicas 14
NULL
c NULL
/* Implementar una COLA introduciendo y eliminando datos, al eliminar liberar memoria */ #include <conio.h> #include <stdio.h> #include <stdlib.h> typedef struct nodo { char dato; struct nodo *enlace; }COLA; void mostrar_cola(COLA*ptr); int vacia(COLA*ptr); void encolar(COLA**cabeza,char item); char desencolar(COLA**cabeza); main() { COLA *cabeza=NULL; encolar (&cabeza,'a'); encolar (&cabeza,'b'); encolar (&cabeza,'c'); printf("La cola es: "); mostrar_cola(cabeza); printf("\n El primer elemento de la cola es %c\n",desencolar(&cabeza)); printf("\n El segundo elemento de la cola es %c\n",desencolar(&cabeza)); printf("\n El tercero elemento de la cola es %c\n",desencolar(&cabeza)); desencolar(&cabeza); getche(); } void mostrar_cola(COLA*ptr) { while(ptr!=NULL) { printf("%c",ptr->dato); ptr=ptr->enlace; } printf("\n"); } int vacia(COLA *ptr)
E. dinmicas 15
{ if (ptr==NULL) return(1); else return(0); } void encolar(COLA**cabeza,char item) { COLA *p; p=(COLA*)malloc(sizeof(COLA)); if (p!=NULL) { p->dato=item; p->enlace=*cabeza; *cabeza=p; } } char desencolar(COLA**cabeza) { COLA *p1,*p2; p1=*cabeza; char item; if(vacia(p1)) { printf("Error! La cola esta vacia\n"); } else { p2=*cabeza; while(p2->enlace!=NULL) { p1=p2; p2=p2->enlace; } item=p2->dato; p1->enlace=NULL; free(p2); if(p1==p2) *cabeza=NULL; return (item); } }
E. dinmicas 16