Вы находитесь на странице: 1из 8

FPR 3evaluacin ASIGNACION DINAMICA DE MEMORIA

DEFINICION DE LISTAS ENLAZADAS Las listas enlazadas se utilizan con estructuras que se crean dinmicamente mediante las funciones malloc() o calloc(). Al crear la lista definimos la estructura y su contenido (puede contener cualquier variable vlida de C como enteros, float, double, char, as como cadenas o matrices) y el nombre de variable. Ej: typedef struct nod { int N; char cad[40]; struct nod *sig; } NODO;
//nombre de la estructura //datos //datos //puntero a la estructura siguiente //nombre de variable (El que usaremos para definir los nuevos elementos)

El puntero *sig se utiliza como enlace entre las estructuras (creadas dinmicamente) y es un elemento fundamental en las mismas. Para trabajar con estructuras de este tipo debemos empezar creando un nodo de inicio que apunte a nulo (NULL). Este ser el que marque el principio de la lista cuando todava no se hayan introducido elementos en la misma, pero al aadir nuevos nodos, ini apuntar al nodo siguiente mientras que este nodo apuntar ahora a null y as sucesivamente al aladir ms nodos a nuestra lista. EJ: NODO *ini=NULL; Al hacer esto tendramos un puntero del tipo que hemos definido pero que apunta a un valor nulo y nos sirve para conocer el principio y el final de la lista, en principio la lista tendra este aspecto: ini NULL

Una vez insertemos el primer elemento, este se colocara justo entre ini y NULL, por tanto ini ahora apuntara al nuevo nodo mientras que el nuevo nodo apuntara a NULL: ini A NULL

A es el puntero a la estructura que acabamos de aadir. Cada nuevo elemento insertado contendr la direccin de una estructura que se encuentra dentro de nuestra lista y a su vez un puntero al elemento siguiente (de ah lo de listas enlazadas). Este puntero al elemento siguiente es el que hemos definido dentro de la estructura como struct nod *sig (la flecha es de los ejemplos es equivalente al puntero sig). Hay que decir que los nodos que insertemos no comparten un espacio contiguo en la memoria y pueden estar en cualquier parte de la misma, esto hace que cobre sentido el hecho de que cada puntero sig incluido en el NODO apunte a una direccin de memoria ocupada por el siguiente elemento.

INSERTAR ELEMENTOS Para insertar los elementos dentro de la lista crearemos un puntero a NODO mediante malloc, esto lo haramos de la siguiente forma: P=(NODO*)malloc(sizeof(NODO)); Para asignar un valor a las variables declaradas dentro de la estructura lo haremos usando -> (signo menos (-) y mayor que (>) sin separacin (->)). p->N=36; p->cad=Manolito; p->sig=ini; Funcin completa para insertar elementos a nuestra lista (solo he puesto que recibe un entero pero puede recibir cualquier cosa): void INSERTAR( int n) { NODO *p; p=(NODO*)malloc(sizeof(NODO)); p->N=n; p->sig=ini; ini=p; } RECORRER LA LISTA A continuacin veremos una funcin que sirve para recorrer la lista y mostrar todos sus elementos: void VER( void) { NODO *aux; aux=ini; while(aux) { printf(Valor %d,aux->N); aux=aux->sig; } }

Veamos ahora un programa completo con lo visto hasta el momento:

#include <vcl\condefs.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> //--------------------------------------------------------------------------------------------------------------------------typedef struct nod { int N; char cad[40]; struct nod *sig; } NODO; //--------------------------------------------------------------------------------------------------------------------------NODO *ini=NULL; //--------------------------------------------------------------------------------------------------------------------------void INSERTAR( int n, char *nota); void VER( void); //--------------------------------------------------------------------------------------------------------------------------void main() { int dato; char nota[40]; for( ; ; ) { printf(Dato: \n); scanf(%d,&dato); if(!dato) {clrscr(); break;} fflush(stdin); printf(Nota: \n); gets(nota); clrscr(); INSERTAR(dato,nota); } VER(); fflush(stdin); getchar(); } void INSERTAR( int n, char *nota ) { NODO *p; p=(NODO*)malloc(sizeof(NODO)); p->N=n; strcpy(p->cad, nota); p->sig=ini; ini=p; } void VER( void) { NODO *aux; aux=ini; while(aux) { printf(Valor %d \nNota: %s\n,aux->N, aux->cad); aux=aux->sig; } } //---------------------------------------------------------------------------------------------------------------------------

BUSCAR UN ELEMENTO EN LA LISTA void BUSCAR( int n) //Podemos enviar cualquier parmetro de bsqueda a la funcin { NODO *aux; //en este caso solo recibe un entero aux=ini; while(aux && aux->N =n) aux=aux->sig; if(aux) printf(Direccin de memoria: %d\nValor:%d\n,aux,aux->N); else printf(%d no est en la lista\n,n); } //---------------------------------------------------------------------------------------------------------------------------

VACIAR LA LISTA void VACIA( ) { NODO *borrar; while(ini){ borrar=ini; ini=borrar->sig; free(borrar); } } //---------------------------------------------------------------------------------------------------------------------------

INSERTAR EN ORDEN void INSERTA(int n ) { NODO *A, *B, *P; P=(NODO*)malloc(sizeof(NODO)); P->N=n; A=B=ini; while(B && B->N<n) // As ordenamos en orden creciente. Para ordenar al revs { A=B; //lo haramos (B && B->N>n) B=B->sig; } P->sig=B; //aqu colocamos el nuevo en su sitio correspondiente if(B==ini) // Si el primer elemento de la lista es mayor que el que queremos introducir ini=P; //Entonces el nuevo elemento ir el primero /*Si nos saltamos este paso y el valor a introducir es ms pequeo que los que incluye la lista, el programa fallar*/ else A->sig=P; //y si no, colocamos el nuevo valor entre A y B chim pum! } //---------------------------------------------------------------------------------------------------------------------------

BORRAR UN ELEMENTO ESPECIFICO void BORRAR_ELEMENTO(int n ) { NODO *A, *B; A=B=ini; while(B && B->N != n) //Mientras no hayan coincidencias recorremos la lista { A=B; B=B->sig; } if(B) { //si B es diferente de NULL if(B==ini) ini=B->sig; // si B es el inicio, el que sigue a B marcar el inicio else A->sig=B->sig; // si no es el inicio, A sig apuntar a B sig free(B); //finalmente liberaremos B } } //--------------------------------------------------------------------------------------------------------------------------INTERCAMBIAR DIRECCIONES ENTRE NODOS DE LISTAS DIFERENTES /* No hace falta declarar 2 estructuras, simplemente hay que hacer 2 inicios diferentes uno para cada lista ya que las dos comparten las variables . Por tanto despus de declarar el NODO, haramos esto : NODO *ini1=*ini2=NULL; */ //En esta funcin se utilizan dos listas, una para los elementos pares y otra para los impares //La lista que recorremos es la de los pares y los que no los son, se asignan a la otra lista void SEPARA( ) { NODO *A, *B; A=B=ip; //ip es el inicio de los pares y ii el inicio de los impares while(B){ //repetiremos todo el proceso hasta comparar todos los elementos while(B && B->N %2== 0) //mientras B sea diferente de null y sea par { A=B; B=B->sig; } if(B) { //si llegamos aqu es que ha encontrado un impar if(B==ip){ //si el impar es el primero en la lista de los pares ip=B->sig; //ahora la lista par empezar por el siguiente elemento B->sig=ii; //esta lnea y la siguiente substituyen al free() ii=B; //hay que tener en cuenta que no queremos eliminarlo, solo cambiarlo A=B=ip; //como B estaba al inicio, volvemos a empezar desde ahi } else { A->sig=B->sig; //saltamos b B->sig=ii; //b apuntar al inicio de la otra lista ii=B; //y finalmente el inicio de de la otra lista apuntara a p B=A->sig; //Seguimos buscando desde la posicin en la que estabamos } } } } //--------------------------------------------------------------------------------------------------------------------------

PILAS Y COLAS Las pilas y las colas son un tipo de listas enlazadas en las cuales, cada vez que provocamos la salida por pantalla del contenido de los nodos, estos se eliminan. Las pilas estn basadas en LIFO (last in first out) , lo que quiere decir que el ltimo nodo en aadirse a la lista ser el primero en ser volcado. Por su parte , las colas se basan en FIFO (first in first out) lo que significa que ser el que primero se aadi a la lista el que saldr antes de ella. Las dunciones utilizadas para insertar o extraer elementos en los dos tipos de listas se suelen llamar Push y Pop respectivamente.

Pila

Push

NODO 3 (ini) NODO 2 NODO 1 NULL

Pop

Como muestra el dibujo, el nodo 3 que se ha insertado en ltimo lugar sera el primero que saldra de la lista (LIFO) pasando ini al nodo 2. La siguiente funcin muestra como insertar elementos en una pila (Push): //-------------------------------------------------------------------------------------------------------------------------void INSERTAR(int n) { NODO *p; P=(NODO*)malloc(sizeof(NODO)); p->dato=n; p->sig=ini; ini=p; } //-------------------------------------------------------------------------------------------------------------------------Y esta otra saca todos los elementos de la lista (Pop): //-------------------------------------------------------------------------------------------------------------------------NODO *SACAR (NODO *n) { NODO *B=ini; if(B) { *n=*B; Ini=B->sig; free(B); } return B; //--------------------------------------------------------------------------------------------------------------------------

Cola En este otro tipo se aade un nuevo puntero a la fiesta, este se declara al mismo tiempo que ini y para aclararnos le llamaremos fin. Este puntero nos servir para saber cual es el ltimo elemento de la lista y por tanto, cual debe abandonar la misma.

Push

NODO 4 (ini) NODO 3 NODO 2 NODO 1 (fin)


Pop

NULL
Est clarsimo, nodo 4 es el que llega en ltimo lugar y pasa a ser el apuntado por ini mientras que nodo 1 que esta apuntado por fin ser el primer en salir, pasando nodo 2 a ser apuntado por fin. La funcin para insertar (Push) en una cola sera: //-------------------------------------------------------------------------------------------------------------------------void INSERTAR(int n) { NODO *P; P=(int*)malloc(sizeof(NODO)); P->valor=n; P->sig=ini; if(fin){ fin->sig=P; fin=P; } else ini=fin=P; } //-------------------------------------------------------------------------------------------------------------------------Y la de sacar (Pop): //-------------------------------------------------------------------------------------------------------------------------NODO *SACAR(NODO *V) { NODO *B=ini; If(ini){ *V=*B; if(ini==fin) ini=fin=NULL; else ini=B->sig; free(B); } return B; // si la funcin borra algn elemento devuelve un valor distinto de NULL } // si no borra nada devuelve NULL //--------------------------------------------------------------------------------------------------------------------------

Вам также может понравиться