Sunteți pe pagina 1din 15

Prof: Eduardo Rosales Meja

Estructuras autorreferenciadas Una estructura autorreferenciada contiene un miembro apuntador, el cual apunta hacia una estructura del mismo tipo. Ejemplo: Struct nodo{ Int dato; Struct nodo *ptrsiguiente; }; Define un tipo structura nodo. Una estructura del tipo struct nodo tiene dos miembros; el miembro entero dato y el miembro apuntador ptrsiguiente. El ptrsiguiente apunta hacia la estructura de tipo struct nodo; una estructura del mismo tipo que la estamos declarando aqu y de ah el trmino estructura autoreferenciada. El miembro ptrsiguiente se conoce como liga, es decir este miembro puede utilizarse para unir una estructura de tipo struct nodo con otra estructura del mismo tipo. Las estructuras autorreferenciadas pueden ligarse entre s para formar estructuras tiles, como las listas, colas , pilas y rboles. Un apuntador NULL generalmente indica el final de una estructura de datos, tal como el carcter nulo indica el final de una cadena. Asignacin de memoria Dinmica Crear y mantener estructuras de datos dinmicas requiere de la asignacin de memoria; es decir, la habilidad de un programa para obtener ms espacio de memoria en tiempo de ejecucin, para almacenar nuevos nodos y para liberar espacio que ya no es necesario. El lmite para la asignacin dinmica de memoria puede ser tan grande como la cantidad de memoria fsica disponible en la computadora, o la virtualmente disponible en un sistema de memoria virtual. Con frecuencia, los limites son mucho ms pequeos debido a que la memoria debe compartirse entre muchas aplicaciones. Las funciones malloc, new y free, y el operador sizeof son bsicas para asiganacin dinmica de memoria. La funcin malloc toma como argumento al nmero de bytes que van a asignarse, y deuelve un apuntador de tipo void* hacia la memoria asignada. Una apuntador void* puede asignarse a una variable de cualquier tipo de apuntador. La funcin malloc normalmente utiliza el operador sizeof. Por ejemplo: Ptrnuevo=malloc(sizeof(struct nodo)); Evalua a sizeof(struct nodo) para determinar el tamao en bytes de una estructura del tipo struct nodo, para asignar una nueva rea en la memoria que coincida con ese numero de bytes, y para almacenar un apuntador a la memoria asignada a la variable

Prof: Eduardo Rosales Meja

ptrnuevo. La memoria asignada no se inicializa. Si no hay memoria disponible, malloc devuelve NULL. La funcin free libera memoria se devuelve al sistema para que sta pueda reasignarse en el futuro. Para liberar memoria dinmica asignada por la llamada a malloc, utilice la instruccin : free(ptrnuevo);

Listas enlazadas
Lista enlazada es una de las estructuras de datos fundamentales, y puede ser usada para implementar otras estructuras de datos. Consiste en una secuencia de nodos, en los que se guardan campos de datos arbitrarios y una o dos referencias (punteros) al nodo anterior y/o posterior. El principal beneficio de las listas enlazadas respecto a los array convencionales es que el orden de los elementos enlazados puede ser diferente al orden de almacenamiento en la memoria o el disco, permitiendo que el orden de recorrido de la lista sea diferente al de almacenamiento. Una lista enlazada es un tipo de dato auto-referenciado porque contienen un puntero o link a otro dato del mismo tipo. Las listas enlazadas permiten inserciones y eliminacin de nodos en cualquier punto de la lista en tiempo constante (suponiendo que dicho punto est previamente identificado o localizado), pero no permiten un acceso aleatorio. Listas simples enlazadas La lista enlazada bsica es la lista enlazada simple la cual tiene un enlace por nodo. Este enlace apunta al siguiente nodo en la lista, o al valor NULL o a la lista vaca, si es el ltimo nodo.

Una lista enlazada simple contiene dos valores: el valor actual del nodo y un enlace al siguiente nodo

Prof: Eduardo Rosales Meja

Pilas
Una pila es una versin restringida de una lista. Los nuevos nodos pueden aadirse y eliminarse de una pila solo en la cima de esta. Por esta razn, a una pila le se conoce como una estructura de datos ultimo entrar, primero en salir. Se hace referencia a una pila por medio de un apuntador hacia el elemento en la cima de la pila. El miembro liga del ultimo nodo de la pila se establece en NULL para indicar el fondo de la pila. Observe que las pilas y las listas enlazadas se representan de manera idntica. La diferencia entre las pilas y las listas es que las inserciones y eliminaciones pueden ocurrir en cualquier parte de la lista ligada, mientras que en una pila, dichas operaciones se realizan solo en la cima de esta. Las funciones bsicas de las pilas son : Empujar: introduce un valor en la pila Sacar: Elimina un valor en la pila. Funcin Empujar:
Void empujar(ptrNodoPila *ptrCima, int info){ ptrNodoPila ptrNuevo; //apuntador al nuevo nodo ptrNuevo=new(NodoPila);//Asignacin de espacio de memoria //Insertar un nodo en la cima de la pila If(ptrNuevo != NULL){ ptrNuevo->dato=info; ptrNuevo->ptrSiguiente=*ptrCima; *ptrCima=ptrNuevo; }//fin del if else{ //si quedara espacio disponible printf(%d No se inserto memoria insuficiente,info) }

1- La funcin crea un nuevo nodo, llamando a new y asigna a ptrNuevo la ubicacin de la memoria asignada.

Prof: Eduardo Rosales Meja

2- Asigna a ptrNuevo->dato el valor a colocarse en la pila y asigna *ptrCima(el apuntador al principio de la pila) a ptrNuevo->ptrSiguiente, el miembro ptrNuevo ahora apunta al nodo cima anterior. 3- Asigna ptrNuevo a *ptrCima , *ptrCima ahora apunta a la nueva cima de la pila.

*ptrCima

ptrNuevo

*ptrCima

ptrNuevo

Funcin Sacar:
int sacar(ptrNodoPila *ptrCima){ ptrNodoPila ptrTemp; //apuntador a un nodo temporal int valorelim//valor del elemento a eliminar ptrTemp = *ptrCima; valorelim=(*ptrCima)->dato;//iguala el dato a valor para //retornarlo y que el usuario sepa cual fue el dato borrado *ptrCima=(*ptrCima)->ptrSiguiente; Free(ptrTemp); Return valorelim; }

Prof: Eduardo Rosales Meja

La funcin sacar elimina un nodo de la cima de la pila. Observe que main determina si la pila est vaca, antes de llamar a sacar. La operacin consiste en 5 pasos: 1- El carcter a eliminar concide con el primer nodo de la pila . Asigne *ptrCima a ptrTemp, ptrTemp se utilizara para liberar la memoria innecesaria. 2- Asigna(*ptrCima)->dato a valorElim para guardar el valor del nodo cima que va a eliminar y despus presentrselo al usuario solo para informarle cual fue el valor que elimino.
3- Asigne (*ptrCima)->ptrSiguiente a *ptrCima, por lo que *ptrCima contiene la direccin del nuevo nodo cima. 4- Libere la memoria apuntada por ptrTemp de la siguiente forma: Free(ptrTemp). 5- Devuelva el valor eliminado a la funcin que hizo la llamada de la siguiente forma: Return valorelim.

*ptrCima

*ptrCima

ptrTemp

Las pilas poseen aplicaciones de inters , por ejemplo siempre que se hace una llamada a funcin , la funcin llamada debe saber cmo regresar a quien la llam, por lo que la direccin de retorno se introduce en una pila. Si se suscita una serie de llamadas a una funcin, los valores de retorno sucesivos se colocan en una pila en el orden ultimo en entrar, primero en salir, por lo que cada funcin puede volver a quien la llam. Las pilas soportan llamadas recursivas a funciones, de la misma manera que soportan llamadas convencionales no recursivas.

Prof: Eduardo Rosales Meja

Las pilas contienen el espacio creado para variables automticas en cada invocacin a una funcin. Cuando la funcin regresa a quien la llam, el espacio de las variables automticas se eliminan de pila y esas variables ya no son conocidas por el programa. Los compiladores utilizan las pilas en el proceso de evaluacin de expresiones y de generaciones de cdigo en lenguaje mquina. Funcin imprimir pila
Void imprimirPila(ptrNodoPila ptrActual){ //verificar si la pila est vaca If(ptrActual == NULL){ Printf(La pila esta vacia); else{ //Mientras no se fin de la pila While(ptrActual !=NULL){ Printf(%d,ptrActual ->dato); ptrActual =ptrActual->ptrSiguiente; }//fin del while }//fin de else } //fin de imprimir pila

Colas

Una cola es una estructura de datos, caracterizada por ser una secuencia de elementos en la que la operacin de insercin push se realiza por un extremo y la operacin de extraccin pop por el otro. Tambin se le llama estructura FIFO (del ingls First In First Out), debido a que el primer elemento en entrar ser tambin el primero en salir. Las colas se utilizan en sistemas informticos, transportes y operaciones de investigacin (entre otros), dnde los objetos, personas o eventos son tomados como datos que se almacenan y se guardan mediante colas para su posterior procesamiento. Este tipo de estructura de datos abstracta se implementa en lenguajes orientados a objetos mediante clases, en forma de listas enlazadas.

Prof: Eduardo Rosales Meja

La particularidad de una estructura de datos de cola es el hecho de que slo podemos acceder al primer y al ltimo elemento de la estructura. As mismo, los elementos slo se pueden eliminar por el principio y slo se pueden aadir por el final de la cola. Ejemplos de colas en la vida real seran: personas comprando en un supermercado, esperando para entrar a ver un partido de bisbol, esperando en el cine para ver una pelcula, una pequea peluquera, etc. La idea esencial es que son todos lneas de espera. Funcin de Insertar
void agregar( ptrNodoCola *ptrCabeza, ptrNodoCola *ptrTalon, char valor ) { ptrNodoCola ptrNuevo; /* apuntador a un nuevo nodo */ ptrNuevo = malloc( sizeof( NodoCola ) ); if ( ptrNuevo != NULL ) { /* es espacio disponible */ ptrNuevo->dato = valor; ptrNuevo->ptrSiguiente = NULL; /* si esta vaca inserta un nodo en la cabeza */ if ( estaVacia( *ptrCabeza ) ) { *ptrCabeza = ptrNuevo; } /* fin de if */ else { ( *ptrTalon )->ptrSiguiente = ptrNuevo; } /* fin de else */

La funcin agregar recibe tres argumentos de main la direccin de un apuntador hacia la cabeza*ptrTalon = ptrNuevo; del apuntador hacia el talon de la cola y el valor a insertar de la cola, la direccin en la}cola. de if */ /* fin La funcin consiste en tres pasos: else { 1- printf( "noCrear un nuevo nodo memoria disponible.\n",new, asignar a ptrNuevo la se inserto %c. No hay llamando a la funcin valor ); ubicacin de la memoria asignada, asignar a ptrNuevo - > dato el valor a insertar } /* fin de elsey*/ en la cola asignar NULL a ptrNuevo - > ptrSiguiente. 2Si la cola sta vaca asigna ptrNuevo a *ptrCabeza de lo contrario, asigna el apuntador ptrNuevo a (*ptrTalon)- > ptrSiguiente.

} /* fin de la funcin agregar */

Prof: Eduardo Rosales Meja

3-

Asigne ptrNuevo a *ptrTalon.

*ptrCabeza

*ptrTalon

*ptrCabez *ptrCabeza

*ptrTalon

La funcin Eliminar:
char retirar( ptrNodoCola *ptrCabeza, ptrNodoCola *ptrTalon ) { char valor; /* valor del nodo */

ptrNodoCola tempPtr; /* apuntador a un nodo temporal */ valor = ( *ptrCabeza )->dato; tempPtr = *ptrCabeza; *ptrCabeza = ( *ptrCabeza )->ptrSiguiente; /* si la cola est vaca */ if ( *ptrCabeza == NULL ) { *ptrTalon = NULL; } /* fin de if */ free( tempPtr ); return valor; } /* fin de la funcin retirar */

Prof: Eduardo Rosales Meja

La funcin sacar elimina un nodo de la cima de la pila. Observe que main determina si la pila est vaca, antes de llamar a sacar. La operacin consiste en 5 pasos: 1- El carcter a eliminar concide con el primer nodo de la pila . Asigne *ptrCabeza a ptrTemp, ptrTemp se utilizara para liberar la memoria innecesaria. 2- Asigna(*ptrCabeza)->dato a valor para guardar el valor del nodo cima que va a eliminar y despus presentrselo al usuario solo para informarle cual fue el valor que elimino.
3- Asigne (*ptrCabeza)->ptrSiguiente a *ptrCabeza, por lo que *ptrCabeza contiene la direccin del nuevo nodo cima. 4- Libere la memoria apuntada por ptrTemp de la siguiente forma: Free(ptrTemp). 5- Devuelva el valor eliminado a la funcin que hizo la llamada de la siguiente forma: Return valor *ptrCabeza *ptrTalon

*ptrCabeza

*ptrTalon

Prof: Eduardo Rosales Meja

La funcin de imprimir cola


/* Imprime la cola */ void imprimeCola( ptrNodoCola ptrActual ) { /* si la cola esta vaca */ if ( ptrActual == NULL ) { printf( "La cola esta vacia.\n\n" ); } /* fin de if */ else { printf( "La cola es:\n" ); /* mientras no sea el final de la cola */ while ( ptrActual != NULL ) { printf( "%c --> ", ptrActual->dato ); ptrActual = ptrActual->ptrSiguiente; } /* fin de while */ printf( "NULL\n\n" ); } /* fin de else */

} /* fin de la funcin imprimeCola */

Arboles

Los arboles son estructuras de datos no lineales de dos dimensiones, con propiedades especiales. Los arboles cuyos nodos contienen dos ligas de las cuales puede ambas o no ser NULL se denominan arboles binarios. El primer nodo del rbol es el nodo raz. Cada liga del nodo raz hace referencia a un hijo. El hijo izquierdo es el primer nodo del subrbol izquierdo y el derecho es el primer nodo del subrbol derecho. A los hijos de un nodo se les conoce como hermanos. A un nodo sin hijos se le conoce como nodo hoja. Un rbol binario de bsqueda (sin valores duplicados de nodos) tiene la caractersticas de que los valores de cualquier subrbol izquierdo son menores que el

Prof: Eduardo Rosales Meja

valor de su nodo padre, y que los valores de y los valores de cualquier subrbol derecho son mayores que el valor de su nodo padre. Funcin de insercin
void insertaNodo( ptrNodoArbol *ptrArbol, int valor ){ /* si el rbol esta vaco */ if ( *ptrArbol == NULL ) { *ptrArbol = malloc( sizeof( NodoArbol ) ); /* si la memoria est asignada, entonces asigna el dato */ if ( *ptrArbol != NULL ) { ( *ptrArbol )->dato = valor; ( *ptrArbol )->ptrIzq = NULL; ( *ptrArbol )->prtDer = NULL; } /* fin de if */ else { printf( "no se inserto %d. No hay memoria disponible.\n", valor ); } /* fin de else */ } /* fin de if */ else { /* el rbol no esta vaco */ /* el dato a insertar es menor que el dato en el nodo actual */ if ( valor < ( *ptrArbol )->dato ) { insertaNodo( &( ( *ptrArbol )->ptrIzq ), valor ); } /* fin de if */ /* el dato a insertar es mayor que el dato en el nodo actual */ else if ( valor > ( *ptrArbol )->dato ) { insertaNodo( &( ( *ptrArbol )->prtDer ), valor ); } /* fin de else if */ else { /* ignora el valor duplicado del dato */ printf( "dup" ); } /* fin de else */

Prof: Eduardo Rosales Meja

La funcin insertaNodo recibe como argumento la direccin del rbol y un entero a almacenarse en el rbol. En un rbol binario de bsqueda, solo puede insertarse un nodo en la forma nodo hoja. Los pasos para insertar un nodo en un rbol binario de bsqueda son: 1- Si *ptrArbol es NULL, crea un nuvo nodo , llamando a la funcin new o malloc, asigna a *ptrArbol la memoria asignada, asigna a (*ptrArbol)->dato el entero a almacenarse asigna el valor NULL a (*ptrArbol)->ptrIzq y a (*ptrArbol)>ptrDer y devuelve el control a quien hizo la llamada. 2- Si el valor de *ptrArbol no es NULL y el valor a insertar es menor que (*ptrArbol)->dato, la funcin insertaNodo es llamada con la direccin de (*ptrArbol)->ptrIzq. Si el valor a insertar es mayor (*ptrArbol)->dato, la funcin insertaNodo es llamada con la direccin (*ptrArbol)->ptrDer. De lo contrario, los pasos recursivos continan hasta que se encuentra un apuntador NULL, despus se ejecuta nuevamente el paso 1 para insertar el nuevo nodo.

Funcin de Borrado La operacin de borrado no es tan sencilla como las de bsqueda e insercin. Existen varios casos a tener en consideracin:
Borrar un nodo sin hijos nodo hoja: simplemente se borra y se establece a nulo el apuntador de su padre.

Nodo a eliminar 74 Borrar un nodo con un subrbol hijo: se borra el nodo y se asigna su subrbol hijo como subrbol de su padre.

Prof: Eduardo Rosales Meja

Nodo a eliminar 70 Borrar un nodo con dos subrboles hijo: la solucin est en reemplazar el valor del nodo por el de su predecesor o por el de su sucesor en inorden y posteriormente borrar este nodo. Su predecesor en inorden ser el nodo ms a la derecha de su subrbol izquierdo (mayor nodo del subarbol izquierdo), y su sucesor el nodo ms a la izquierda de su subrbol derecho (menor nodo del subarbol derecho). En la siguiente figura se muestra cmo existe la posibilidad de realizar cualquiera de ambos reemplazos:

Nodo a eliminar 59

El procedimiento reemplazar busca la mayor clave del subrbol izquierdo y la asigna al nodo a eliminar.

Prof: Eduardo Rosales Meja

void suprime(TREENODEPTR *A,int info) { TREENODEPTR *B; if (*A == NULL) printf("ERROR..EL ELEMENTO NO SE ENCUENTRA"); else { if (info < (*A)->data) suprime(&((*A)->izq),info); else if (info > (*A)->data) suprime(&((*A)->der),info); else if ((*A)->izq == NULL) { *B = *A; *A = (*A)->der; free(B); } else if ((*A)->der == NULL) { *B = *A; *A = (*A)->izq; free(B); } else { *B = ((*A)->der); (*A)->data =(*B)->data; suprime(&((*A)->der),((*A)->data)); } } printf("\n ELEMENTO ELIMINADO\n"); }

Prof: Eduardo Rosales Meja

S-ar putea să vă placă și