Anda di halaman 1dari 10

1 Estructuras Autorreferenciadas

Estructuras Autorreferenciadas 1. Listas. Una lista es un conjunto de datos relacionados entre s, creados en forma dinmica. Se pude decir que cada elemento es una estructura autoreferenciada (uno de sus datos es un puntero a su misma estructura). La idea es aprovechar la asignacin dinmica de memoria para crear los elementos necesarios y facilitar su mantenimiento, ya que es relativamente sencillo agregar eliminar un elemento de la lista. Por ser una estructura autoreferenciada: Ejemplo: #define ELEMENTO struct elemento ELEMENTO { int dato; ELEMENTO *lazo; }; Cada elemento tiene una parte informativa (dato) y otra puntero (lazo) a una estructura de su mismo tipo.

En el ejemplo el dato es un int pero puede cualquier tipo vlido. El puntero es asignado a la direccin de la siguiente dato de la lista. A los datos se accede mediante puntero, y el dato en general es una estructura por ejemplo supongamos que tenemos un puntero p y queremos saber el dato: printf("%d", (*p).dato); El parntesis es necesario por la precedencia de los operadores . (punto) y * (asterisco). Para simplificar esto el c tiene otra notacin para manejar punteros a estructuras. printf("%d", p->dato);

2 Estructuras Autorreferenciadas

->: Es directamente el objeto del campo. Las operaciones bsicas de una lista son * Creacin. * Altas. * Bajas. 1.1. Pilas. En esta seccin se ver el uso de pilas utilizando asignacin dinmica de memoria. Recordemos que en una estructura pila el primero en entrar es el ltimo en salir. 1.1.1. Creacin de una pila. Para crear una pila se necesita una estructura idntica a la vista: struct pila { int dato; struct pila * l; /* lazo */ }; Se utilizara tres punteros, *p: puntero al primer elemento de la pila , *aux: auxiliar y un tercero (aunque no es tcnicamente necesario se coloca para facilitar la comprensin del tema) de recorrido *r. main(void) { int inf; struct pila *p,*aux ,*r; p=aux=r=NULL; /* Los punteros no apuntan a nada */ Ahora debemos hacer una iteracin para que lea datos hasta completar todos los datos, en este ejemplo se toma la opcin de salida cuando el dato sea igual a cero. while(1) /* Bucle infinito */ { printf("\nIngrese la informacin (Sale con 0):"); scanf("%d",&inf); if(!inf) break; /* Condicin de salida */ /* ( 1 ) */ aux = (struct pila *) malloc(sizeof(struct pila)); /* Reserva un lugar para un elemento */ aux.dato =inf; /* Coloca la informacin en dato */

3 Estructuras Autorreferenciadas

/* ( 2 ) */aux->l = p; /* l (lazo) apuna a p (primero), para la primera iteracin NULL, el primero que entra , el lazo apunta a nada. */ /* ( 3 ) */ p = aux; /* p apunta donde apunta el auxiliar */

Luego de estas dos instrucciones quedar:

} /* termina el ciclo */ Repetiremos el ciclo para que se vea como se va confeccionando la pila. Usaremos una X para indicar que un puntero no apunta a ningn lado ( NULL ).

( 1 ) Asigno memoria. aux = (struct pila *) malloc(sizeof(struct pila));

( 2 ) aux->l = p; lazo apunta al primero.

4 Estructuras Autorreferenciadas

(3) p = aux; puntero apunta al auxiliar.

Antes de seguir se debe aclarar, que cuando se dibuja con una flecha un puntero, ste apunta al principio de la estructura, no importa que en zona del grfico de la estructura apunte.

aux y p apuntan al mismo lugar. Observar que p siempre queda apuntando al primer elemento y aux es usado para crear elementos. Si se pierde el primer elemento por ejemplo la pila no se podr acceder nunca y la memoria asignada permanecer ah, quedando los datos en memoria sin poder acceder a los mismos y ocupando lugar. Siempre se debe tener un puntero al primer elemento. Para crear una pila los pasos a seguir son los siguientes: ( 1 ) Reservar el lugar dinmicamente (En aux ). ( 2 ) Asignarle los datos a la parte informativa de la estructura pila. ( 3 ) El lazo de la estructura apunte al primero (para que funcione con todos los elementos antes de empezar el proceso iterativo p = NULL). ( 4 ) El primero se apuntar al elemento creado en (1). 1.1.2. Recorrido de una Pila.

5 Estructuras Autorreferenciadas

Para ver el dato del primer elemento de la pila se tendr que hacer: printf("\n %d",p->dato); Si se quiere el segundo elemento sera: printf("\n %d", p->l->dato); ya que p->l es el objeto de p , campo l , que a su ves es un puntero a la siguiente estructura al aplicarle l->dato es el campo dato al cual apunta l.

Si fuera el tercero printf("\n %d",p->l->l->dato); Como se ve esta forma de acceder a los datos no es muy cmoda. Una forma de solucionar este inconveniente es recorrer la pila moviendo el puntero. El puntero a mover no tiene que ser p (el primero) sino un auxiliar. Lo primero que hay que hacer es pasarle la direccin del primer elemento. aux=p; Se va a imprimir toda la pila. while( 1 ) { if(!aux) break; /* No hay ms elementos */ printf("\n%d",aux->dato); aux=aux->l; /* Se mueve el puntero al siguiente elemento */ } 1.1.3. Problemas. Problema 46: Crear una Pila(Estructura dinmica) con elementos del siguiente tipo: nombre char 25 - direccin char 30 - te char 10.#include<stdio.h> #include<stdlib.h> #include<alloc.h> #include<string.h> void main(void) { char c,s[30];

6 Estructuras Autorreferenciadas

struct pila { char nombre[25],direccion[30],te[10]; struct pila *l; }; struct pila *p,*aux; p=aux=NULL; while(1) { printf("\n (1) Sigue --- (2) Sale\n"); c=getch(); if(c=='2') break; /* sale con 2 */ aux=(struct pila *) malloc(sizeof(struct pila)); if(aux) { printf("\n Nombre:"); gets(s); strcpy(aux->nombre,s); printf("\n Direccin:"); gets(s); strcpy(aux->direccion,s); printf("\n Te:"); gets(s); strcpy(aux->te,s); aux->l=p; p=aux; } else printf("\n Memoria Saturada"); } /* while */
/* listado de la pila */

aux=p; while(1) { if(!aux) break; printf("\n%s -- %s -- %s",aux->nombre,aux->direccion,aux->te); aux=aux->l; } getch(); } Problema 47: Un programa igual al anterior usando funciones. #include <stdio.h> #include <stdlib.h> #include <alloc.h> #include <string.h> struct pila { char clave[5],nombre[20],te[10]; struct pila *l;

7 Estructuras Autorreferenciadas

}; struct pila * agregar(struct pila * primero); void listar(struct pila * primero); void main(void) { struct pila *p; char c; while(1) { printf("\n (1) Sigue. -- (2) Sale."); c=getch(); if(c=='2') break; p=agregar(p); } listar(p); } struct pila * agregar(struct pila * primero) { struct pila *aux; aux=(struct pila *)malloc(sizeof(struct pila)); if(aux) { printf("\nClave: "); gets(aux->clave); printf("Nombre: "); gets(aux->nombre); printf("Telfono: "); gets(aux->te); } else printf("\n No hay memoria"); aux->l=primero; return aux; /* Equivale a primero=aux */ } void listar(struct pila * primero) { struct pila *aux; aux=primero; while(1) { if(!aux) break; printf("\n %4s -- %20s -- %10s",aux->clave,aux->nombre,aux->te); aux=aux->l; } } 1.1.4. Insertar un elemento.

8 Estructuras Autorreferenciadas

Una de las ventajas de una pila dinmica respecto a una esttica es la insercin de un elemento en cualquier lugar de la pila. En realidad esto rompe con la definicin de pila, ya que el primero de la pila es el que se debera eliminar. Es por ello la estructura de dato dinmica tiene la posibilidad de insertar o eliminar elementos en cualquier posicin se la denomina Listas. Para realizar una insercin debemos saber en que lugar va a ir el nuevo elemento si la pila/lista esta ordenada por algn criterio buscar el lugar donde debe ser ubicado ese elemento. 1.1.4.1. Insertar en un lugar dado. Para ello se dar el lugar a partir del primer elemento en el cual se quiere colocar. (1) Se pasa el valor del primero a un auxiliar. aux = p; (2) Por la forma que estn enganchados deber mover hasta la posicin del anterior. Como aux ya apunta al primero se deber mover el puntero una cantidad de veces igual a lugar-2. for(i=0;i<(lugar-2); i++) { aux=aux->lazo; if(!aux) break; } Si se quiere colocar en 2do. lugar no muevo el puntero, en el tercero se mueve una ves, etc. Una insercin en el primer lugar ser agregar un elemento, no un procedimiento de insercin.

(3) Ya posicionado aux con otro puntero nuevo se generar el espacio para el nuevo

9 Estructuras Autorreferenciadas

elemento y luego se cargaran los datos. nuevo=(struct pila *) malloc(sizeof(struct pila));

(4) Se debe enganchar el lazo del elemento creado ( aux1->lazo ) con el siguiente de auxiliar ( aux->lazo ). aux1->lazo=aux->lazo;

(5) Por ltimo se deber enlazar aux->lazo con el nuevo elemento. aux->lazo = aux1;

10 Estructuras Autorreferenciadas

Salvo el primer elemento que sera agregar esto es vlido para todos los elementos incluido el ltimo. Antes de tratar de insertar el elemento en algn lugar se deber verificar que aux!=NULL ya que si fuera as la posicin pedida no se encuentra en la pila. Ejemplo: una pila de 10 elementos insertar uno en el lugar 25.

Anda mungkin juga menyukai