¡De nada!
Todo el mundo tiene algun patinazo de vez en cuando, servidor incluido
, faltaria mas.
¡Saludos!
Todo el mundo tiene algun patinazo de vez en cuando, servidor incluido
, faltaria mas.¡Saludos!
Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.
Mostrar Mensajes Menú
, faltaria mas.
por el!
int (*cmp)(void*,void*) Esta funcion la ha de aportar el usuario del codigo. Es un funcion para poder comparar los valores clave. He aqui algunos ejemplos:
int incmp(void* a,void* b)
{
return *((int*)a) - *((int*)b;
}
int stringcmp(void* s1, void* s2)
{
return strcmp((char*)s1,(char*)s2);
}
int fechacmp(void* f1,void* f2)
{
if(((Fecha*)f1)->año > ((Fecha*)f2)->año)
return 1; /* la primera fecha es mayor*/
if(((Fecha*)f1)->año < ((Fecha*)f1)->año)
return -1; /* la primera fecha es menor*/
/* ... */
}
struct Tonteria
{
int x;
float y;
char a;
};
#include "ADTlist.h"
#include "ADTlist.c" /* solo si no se va crear un proyecto */
struct Tonteria
{
int x;
float y;
char a;
};
typedef struct Tonteria Tonteria;
int tonteriacmp(void* t1,void* t2);
int intcmp(void* a,void* b);
int main(int argc, char* argv[])
{
Tonteria unaTonteria;
ADTList *listaTonta=NULL, *listaInt=NULL;
int entero=5;
Tonteria.x = 7;
ADTListInsert(&listaTonta, &unaTonteria, &unaTonteria.x, sizeof(Tonteria), tonteriacmp);
ADTListInsert(&listaInt, &entero, &entero, sizeof(int), intcmp);
return 0;
}
int tonteriacmp(void* t1,void* t2)
{
return ((Tonteria*)t1)->x - ((Tonteria*)t2)->x;
}
int intcmp(void* a,void* b)
{
return *((int*)a) - *((int*)b);
}
#ifndef ADT_STACK_H
#define ADT_STACK_H
#include <stdlib.h>
#include <string.h>
#ifndef ADT_STACK_FLAGS
#define ADT_STACK_FLAGS
#define ADT_STACK_OK 0L
#define ADT_STACK_NOT_ENOUGH_MEMORY 1L
#define ADT_STACK_EMPTY_STACK 2L
#endif /* ADT_STACK_FLAGS */
struct ADTStackNode
{
void *Data; /* guarda la informacion de los datos que maneja la pila */
struct ADTStackNode *Next; /* apunta al siguiente elemento de la pila */
};
typedef struct ADTStackNode ADTStackNode;
typedef ADTStackNode* pADTStackNode;
typedef pADTStackNode ADTStack;
/* funcion para inicializar un nodo completamente a cero*/
void ADTStackNodeIni(pADTStackNode pNode);
/* Comprueba si top == NULL, equivalentemente, si la pila esta vacia */
int ADTStackIsEmpty(pADTStackNode top);
/* Guarda un valor en la pila. size == sizeof el tipo de dato al que apunta data. */
unsigned long ADTStackPush(pADTStackNode* top,void* data,size_t size);
/* Saca un valor de la pila y lo pone en data. size==sizeof el tipo de dato al que apunta data */
unsigned long ADTStackPop(pADTStackNode* top,void* data,size_t size);
#endif /* ADT_STACK_H */
#include "ADTstack.h"
void ADTStackNodeIni(pADTStackNode pNode)
{
/* inicializamos a cero la variable */
memset(pNode,0,sizeof(ADTStackNode));
}
int ADTStackIsEmpty(pADTStackNode top)
{
return top==NULL;
}
unsigned long ADTStackPush(pADTStackNode* top,void* data,size_t size)
{
pADTStackNode newNode=NULL; /* puntero al nodo que guardara la nueva informacion */
/* intentamos asignar un nuevo nodo */
if(!(newNode = (ADTStackNode *)malloc(sizeof(ADTStackNode))))
return ADT_STACK_NOT_ENOUGH_MEMORY; /* si no se puede enviamos un aviso */
/* inicalizamos el nuevo nodo */
ADTStackNodeIni(newNode);
/* intentamos asignar memoria para almacenar los datos que haya que introducir en la pila */
if(!(newNode->Data = malloc(size)))
{
/* si no se puede asignar la memoria */
free(newNode); /* liberamos la memoria anteriormente asignada */
return ADT_STACK_NOT_ENOUGH_MEMORY; /* y devolvemos un aviso */
}
/* copiamos la informacion en el nuevo nodo */
memcpy(newNode->Data , data , size);
/* y hacemos que el nuevo nodo sea el superior de la pila */
newNode->Next = (*top); /* pasando el nodo superior a ser el segundo */
(*top) = newNode; /* y asignando el puntero superior al nuevo nodo*/
return ADT_STACK_OK; /* todo correcto */
}
unsigned long ADTStackPop(pADTStackNode* top,void* data,size_t size)
{
ADTStackNode *aux; /* para saber donde esta el segundo nodo una vez borrado el primero */
/* no se podra sacar nada de una pila vacia */
if((*top) == NULL)
return ADT_STACK_EMPTY_STACK;
/* apuntamos donde esta el segundo nodo */
aux = (*top)->Next;
/* copiamos el valor que sera borrado en data */
memcpy(data , (*top)->Data , size);
/* eliminamos la informacion contenida en el primer nodo */
free((*top)->Data);
/* liberamos el primer nodo */
free(*top);
/* y hacemos que el segundo nodo pase a ser el primero */
(*top) = aux;
return ADT_STACK_OK; /* todo correcto */
}
#include <stdio.h>
#include "ADTstack.h"
struct Tonteria
{
char c;
int x;
float y;
};
typedef struct Tonteria Tonteria;
void mostrarTonteria(Tonteria *t);
int main()
{
ADTStackNode *pilaTonta=NULL;
Tonteria tontada;
int i;
printf("PUSH\n");
printf("====\n");
for(i=0 ; i < 10 ; i++)
{
tontada.c = rand() % (255 - 32) + 32; /* generamos un caracter imprimible */
tontada.x = rand() % 100; /* 0 - 99 */
tontada.y = tontada.x / 10.; /* 0 - 9'9 */
/* mostramos la informacion */
mostrarTonteria(&tontada);
/* y la guardamos en la pila */
ADTStackPush(&pilaTonta , &tontada , sizeof(Tonteria));
}
printf("\n");
printf("Pulsar intro...");
getchar();
printf("\n");
printf("POP\n");
printf("===\n");
while(!ADTStackIsEmpty(pilaTonta))
{
/* extraemos el valor superior, que sera almacenado en tontada */
ADTStackPop(&pilaTonta , &tontada , sizeof(Tonteria));
/* y lo mostramos para comprobar que los valores se invierten y que la pila funciona */
mostrarTonteria(&tontada);
}
printf("\n");
printf("Pulsar intro...");
getchar();
printf("\n");
return 0;
}
void mostrarTonteria(Tonteria *t)
{
printf("[%c , %02d , %3.1f]\n", t->c , t->x , t->y);
}
#ifndef ADT_QUEUE_H
#define ADT_QUEUE_H
#include <stdlib.h>
#include <string.h>
#ifndef ADT_QUEUE_FLAGS
#define ADT_QUEUE_FLAGS
#define ADT_QUEUE_OK 0L
#define ADT_QUEUE_NOT_ENOUGH_MEMORY 1L
#define ADT_QUEUE_EMPTY_QUEUE 2L
#endif /* ADT_QUEUE_FLAGS */
struct ADTQueueNode
{
void *Data;
struct ADTQueueNode *First;
struct ADTQueueNode *Last;
struct ADTQueueNode *Next;
};
typedef struct ADTQueueNode ADTQueueNode;
typedef ADTQueueNode ADTQueue;
typedef ADTQueueNode* pADTQueueNode;
/* funcion para inicializar un nodo completamente a cero*/
void ADTQueueNodeIni(pADTQueueNode pNode);
/* Comprueba si la cola esta vacia */
int ADTQueueIsEmpty(pADTQueueNode queue);
/* Guarda un valor en la cabeza de la cola. size == sizeof el tipo de dato al que apunta data. */
unsigned long ADTQueueEnqueue(pADTQueueNode *first,pADTQueueNode *last,void* data,size_t size);
/* Saca un valor de la cola de la cola :P y lo pone en data. */
unsigned long ADTQueueDequeue(pADTQueueNode *first,pADTQueueNode *last,void* data,size_t size);
#endif /* ADT_QUEUE_H */
#include "ADTqueue.h"
void ADTQueueNodeIni(pADTQueueNode pNode)
{
/* ponemos la variable a cero */
memset(pNode,0,sizeof(ADTQueueNode));
}
int ADTQueueIsEmpty(pADTQueueNode queue)
{
/* comprobamos si hay datos o no en la cabeza de la cola */
return queue->First == NULL;
}
unsigned long ADTQueueEnqueue(pADTQueueNode *first,pADTQueueNode *last,void* data,size_t size)
{
ADTQueueNode *newNode; /* puntero a un nuevo nodo de la cola */
/* si no podemos asignar memoria para el nuevo nodo */
if(!(newNode = (ADTQueueNode *) malloc(sizeof(ADTQueueNode))))
return ADT_QUEUE_NOT_ENOUGH_MEMORY; /* damos el aviso */
/* inicializamos el nuevo nodo */
ADTQueueNodeIni(newNode);
/* si no podemos asignar espacio para que el nuevo nodo contenga datos */
if(!(newNode->Data = malloc(size)))
{
free(newNode); /* eliminamos el espacio que ocupa el nodo */
return ADT_QUEUE_NOT_ENOUGH_MEMORY; /* y damos el aviso */
}
/* copiamos la informacion en el nuevo nodo */
memcpy(newNode->Data , data , size);
/* si la lista esta vacia */
if(!(*first))
(*first) = newNode; /* la cabeza de la cola apunta al nuevo elemento */
else /* sino */
(*last)->Next = newNode; /* añadimos el nuevo elemento al final de la cola */
(*last) = newNode; /* y el nuevo nodo pasa a ser el ultimo de la cola */
return ADT_QUEUE_OK;
}
unsigned long ADTQueueDequeue(pADTQueueNode *first,pADTQueueNode *last,void* data,size_t size)
{
ADTQueueNode* aux; /* puntero para no perder de vista el segundo elemento de la cola */
/* si la cola esta vacia */
if(!(*first))
return ADT_QUEUE_EMPTY_QUEUE; /* avisamos de ello */
/* guardamos la posicion del segundo elemento */
aux = (*first)->Next;
/* recuperamos los datos del primer elemento */
memcpy(data , (*first)->Data , size);
/* liberamos la informacion y el espacio del primer elemento */
free((*first)->Data);
free(*first);
/* y hacemos que el segundo elemento pase a la cabeza de la cola */
(*first) = aux;
/* si no hay mas elementos */
if(!(*first))
(*last) = NULL; /* marcamos el ultimo tambien a NUlL */
return ADT_QUEUE_OK; /* todo correcto */
}
#include <stdio.h>
#include "ADTqueue.h"
struct Tonteria
{
char c;
int x;
float y;
};
typedef struct Tonteria Tonteria;
void mostrarTonteria(Tonteria *t);
int main()
{
ADTQueueNode colaTonta;
Tonteria tontada;
int i;
/* inicializamos de forma correcta el nodo inicial */
ADTQueueNodeIni(&colaTonta);
printf("ENQUEUE\n");
printf("=======\n");
for(i=0 ; i < 10 ; i++)
{
tontada.c = rand() % (255 - 32) + 32; /* generamos un caracter imprimible */
tontada.x = rand() % 100; /* 0 - 99 */
tontada.y = tontada.x / 10.; /* 0 - 9'9 */
/* mostramos la informacion */
mostrarTonteria(&tontada);
/* y la guardamos en la cola */
ADTQueueEnqueue(&colaTonta.First , &colaTonta.Last, &tontada , sizeof(Tonteria));
}
printf("\n");
printf("Pulsar intro...");
getchar();
printf("\n");
printf("\n");
printf("DEQUEUE\n");
printf("=======\n");
/* mientras queden elementos en la cola */
while(!ADTQueueIsEmpty(&colaTonta))
{
/* extraemos el valor superior, que sera almacenado en tontada */
ADTQueueDequeue(&colaTonta.First , &colaTonta.Last, &tontada , sizeof(Tonteria));
/* y lo mostramos para comprobar que los valores salen en orden y que la cola funciona */
mostrarTonteria(&tontada);
}
printf("\n");
printf("Pulsar intro...");
getchar();
printf("\n");
return 0;
}
void mostrarTonteria(Tonteria *t)
{
printf("[%c , %02d , %3.1f]\n", t->c , t->x , t->y);
}
#ifndef ADT_LIST_H
#define ADT_LIST_H
#include <stdlib.h>
#include <string.h>
#include "ADTqueue.h"
#ifndef ADT_LIST_FLAGS
#define ADT_LIST_FLAGS
#define ADT_LIST_OK 0L
#define ADT_LIST_NOT_ENOUGH_MEMORY 1L
#define ADT_LIST_EMPTY_LIST 2L
#define ADT_LIST_ITEM_NOT_FOUND 4L
#endif /* ADT_LIST_FLAGS */
struct ADTListNode
{
void *Data;
struct ADTListNode *Next;
};
typedef struct ADTListNode ADTListNode;
typedef struct ADTListNode ADTList;
typedef struct ADTListNode* pADTListNode;
/* inicializamos la estructura para futuros usos */
void ADTListNodeIni(pADTListNode pNode);
/* comprueba si la lista esta vacia */
int ADTListIsEmpty(pADTListNode List);
/* inserta un nuevo item en la lista */
unsigned long
ADTListInsert(pADTListNode *List, void *data, void *key, size_t size, int (*cmp)(void*,void*));
/* elimina un item de la lista */
unsigned long
ADTListDelete(pADTListNode *List, void *data, void *key, size_t size, int (*cmp)(void*,void*));
/* busqueda de items en la lista */
void* ADTListSearch(pADTListNode *List, void *data, void *key, int (*cmp)(void*,void*));
/* libera la memoria ocupada por la lista y la pasa a una cola, que es mas facil de liberar */
unsigned long ADTListDestroy(pADTListNode *List, size_t dataSize , ADTQueueNode *pQueue);
/* retorna el primer elemento de la lista (facilita la liberacion de la memoria) */
unsigned long
ADTListFirst(pADTListNode *List, void *data, size_t size);
#endif /* ADT_LIST_H */
#include "ADTlist.h"
void ADTListNodeIni(pADTListNode pNode)
{
/* inicializamos los datos a cero */
memset(pNode,0,sizeof(ADTListNode));
}
int ADTListIsEmpty(pADTListNode List)
{
/* ¬¬ */
return List==NULL;
}
unsigned long
ADTListInsert(pADTListNode *List, void *data, void *key, size_t size, int (*cmp)(void*,void*))
{
/* punteros para no perdes la pista al nodo anterior y siguiente de la busqueda de la posicion
del nuevo elemento, y el ultimo puntero sirve para asignar la memoria del nuevo dato */
ADTListNode *previous,*current,*newNode;
/* intentamos asignar memoria para el nuevo nodo */
if(!(newNode = (ADTListNode*) malloc(sizeof(ADTListNode))))
return ADT_LIST_NOT_ENOUGH_MEMORY; /* si no se puede damos el aviso */
/* inicializamos el nuevo nodo */
ADTListNodeIni(newNode);
/* si no se puede asignar memoria para el nuevo dato */
if(!(newNode->Data = malloc(size)))
{
free(newNode); /* liberamos la memoria del nodo */
return ADT_LIST_NOT_ENOUGH_MEMORY; /* y avisamos de lo sucedido */
}
/* copiamos al nuevo nodo los datos que se quieren guardar */
memcpy(newNode->Data , data , size);
/* inicalizamos los punteros auxiliares */
previous = NULL;
current = (*List);
/* mientras no se haya alcalzado el final de la lista y la comparacion del nuevo elemento con
el actual sea mayor (se insertaran por orden creciente de valores de comparacion) */
while(current && cmp(key , (char*)(current->Data) + ((char*)key - (char*)data))>0)
{
previous = current; /* el puntero actual pasa a ser el anterior */
current = current->Next; /* el puntero siguiente al actual pasa a ser el actual */
}
/* si no hay elemento anterior, no se ha realizado ninguna iteracio, por lo que el nuevo
elemento debe ser el primero de la lista*/
if(!previous)
{
newNode->Next = (*List);
(*List) = newNode;
}
else /* si existe un nodo anterior */
{
/* el nuevo valor tiene que intercalarse entre el anterior y el actual */
previous->Next = newNode;
newNode->Next = current;
}
return ADT_LIST_OK; /* todo correcto */
}
unsigned long
ADTListDelete(pADTListNode *List, void *data, void *key, size_t size, int (*cmp)(void*,void*))
{
/* punteros auxiliares para controlar la posicion del nodo que debe ser borrado */
ADTListNode *previous,*current;
/* no se puede eliminar nada de una lista vacia */
if(!(*List))
return ADT_LIST_EMPTY_LIST;
/* iniciazliamos los punteros auxiliares */
previous = NULL;
current = (*List);
/* mientras no se haya alcalzado el final de la lista y la comparacion del nuevo elemento con
el actual sea mayor (los elementos estan insertados por orden creciente) */
while(current && cmp(key ,(char*)(current->Data) + ((char*)key - (char*)data))>0)
{
previous = current; /* anterior = actual */
current = current->Next; /* el siguiente al actual pasa a ser el nuevo actual */
}
/* si se ha alcanzado el final de la lista */
if(!current)
return ADT_LIST_ITEM_NOT_FOUND; /* significa que el elemento no existe */
/* si la comparacion no es igual */
if(cmp(key ,(char*)(current->Data) + ((char*)key - (char*)data)))
return ADT_LIST_ITEM_NOT_FOUND; /* el elemento no existe */
/* copiamos la informacion contenida antes de borrar el nodo */
memcpy(data , current->Data , size);
/* si no hay anterior*/
if(!previous)
(*List) = (*List)->Next; /* hay que eliminar el primer nodo */
else /* sino */
previous->Next = current->Next /* el anterior salta al actual */;
/* liberamos los datos del nodo y el propio nodo */
free(current->Data);
free(current);
return ADT_LIST_OK; /* todo correcto */
}
void* ADTListSearch(pADTListNode *List, void *data, void *key, int (*cmp)(void*,void*))
{
/* puntero auxiliar para recorrer la lista */
ADTListNode *current;
current = (*List);
/* mientras no se haya alcalzado el final de la lista y la comparacion del nuevo elemento con
el actual sea mayor (se insertaran por orden creciente de valores de comparacion) */
while(current && cmp(key ,(char*)(current->Data) + ((char*)key - (char*)data))>0)
current = current->Next;
/* si se ha alcanzado el final de la lista */
if(!current)
return NULL; /* no se ha encontrado el elemento y se devuelve NULL */
/* si el elemento actual es mayor que el buscado, el elemento buscado no existe */
if(cmp(key ,(char*)(current->Data) + ((char*)key - (char*)data)))
return NULL;
/* retornamos un puntero al valor encontrado */
return current->Data;
}
unsigned long ADTListDestroy(pADTListNode *List, size_t dataSize , ADTQueueNode *pQueue)
{
unsigned long ret;
/* lista vacia o final de la lista */
if(!(*List))
return ADT_LIST_EMPTY_LIST; /* avisamos */
/* almacenamos el valor de retorno para ver que ha sucedido al eliminar el resto de nodos */
ret = ADTListDestroy(&((*List)->Next) , dataSize , pQueue);
/* los unicos valores que retorna la funcion de forma directa son ADT_LIST_EMMPTY_LIST, que
indica que se ha llegado al final de la lista, o ADT_LIST_OK, que indica que de momento no
ha ocurrido ningun error. Ambos valores son indicativos de que no hay errores.
Si ADTQueueEnqueue retorna ADT_QUEUE_OK, este valor es igual a ADT_LIST_OK por definicion
El resto de los valores que puede retornar provienen de algun posible error a la hora de
manipular la cola que almacenara los datos de la lista
*/
if(ret == ADT_LIST_EMPTY_LIST || ret == ADT_LIST_OK)
{
/* en este punto no ha habido ningun error */
/* intentamos almacenar el siguiente valor en la cola */
if(!(ret = ADTQueueEnqueue(&(pQueue->First), &(pQueue->Last), (*List)->Data, dataSize)))
{
/* se ha podido insertar el valor en la cola */
/* liberamos la informacion contenida en el nodo actual y el propio nodo */
free((*List)->Data);
free((*List));
return ADT_LIST_OK; /* y avisamos de que todo va bien */
}
}
/* si se llega a este punto, ha habido algun error */
return ret; /* avisamos del error ocurrido */
}
unsigned long
ADTListFirst(pADTListNode *List, void *data, size_t size)
{
/* no hay primer elemento en una lista vacia */
if(!(*List))
return ADT_LIST_EMPTY_LIST;
/* copiamos la informacion del primer elemento */
memcpy(data , (*List)->Data , size);
return ADT_LIST_OK; /* todo correcto */
}
#include <stdio.h>
#include "ADTlist.h"
struct Tonteria
{
char c;
int x;
float y;
};
typedef struct Tonteria Tonteria;
int intcmp(void *a,void *b);
void mostrarTonteria(Tonteria *t);
int main()
{
ADTListNode *listaTonta=NULL;
Tonteria tontada , *pTonto;
int i;
printf("INSERCION\n");
printf("=========\n");
for(i=0 ; i < 10 ; i++)
{
tontada.c = rand() % (255 - 32) + 32; /* generamos un caracter imprimible */
tontada.x = rand() % 100; /* 0 - 99 */
tontada.y = tontada.x / 10.; /* 0 - 9'9 */
/* mostramos la informacion */
mostrarTonteria(&tontada);
/* y la guardamos en la lista ordenando los elementos por el valor x */
ADTListInsert(&listaTonta , &tontada , &tontada.x , sizeof(Tonteria) , intcmp);
}
printf("\n");
getchar();
printf("BUSQUEDA\n");
printf("========\n");
/* aunque no se retorne ningun valor en tontada, es necesario pasar el puntero para que la
funcion puede calcular el desplazamiento que tiene el campo clave dentro del struct */
if((pTonto = (Tonteria*) ADTListSearch(&listaTonta , &tontada , &tontada.x , intcmp)))
{
printf("%d se encuentra en la lista.\n",pTonto->x);
}
else
{
printf("%d no se encuentra en la lista.\n",tontada.x);
}
tontada.x = 5;
if((pTonto = (Tonteria*) ADTListSearch(&listaTonta , &tontada , &tontada.x , intcmp)))
{
printf("%d se encuentra en la lista.\n",pTonto->x);
}
else
{
printf("%d no se encuentra en la lista.\n",tontada.x);
}
tontada.x = 27;
if((pTonto = (Tonteria*) ADTListSearch(&listaTonta , &tontada , &tontada.x , intcmp)))
{
printf("%d se encuentra en la lista.\n",pTonto->x);
}
else
{
printf("%d no se encuentra en la lista.\n",tontada.x);
}
printf("\n");
getchar();
printf("ELIMINAR DATO\n");
printf("=============\n");
tontada.x = 27;
ADTListDelete(&listaTonta , &tontada , &tontada.x , sizeof(Tonteria) , intcmp);
if((pTonto = (Tonteria*) ADTListSearch(&listaTonta , &tontada , &tontada.x , intcmp)))
{
printf("%d se encuentra en la lista.\n",pTonto->x);
}
else
{
printf("%d no se encuentra en la lista.\n",tontada.x);
}
printf("\n");
getchar();
printf("VACIADO\n");
printf("=======\n");
while(!ADTListIsEmpty(listaTonta))
{
ADTListFirst(&listaTonta , &tontada , sizeof(Tonteria));
ADTListDelete(&listaTonta , &tontada , &tontada.x ,sizeof(Tonteria) , intcmp);
printf("Eliminado: ");
mostrarTonteria(&tontada);
}
getchar();
return 0;
}
int intcmp(void *a,void *b)
{
return *((int*)a) - *((int*)b);
}
void mostrarTonteria(Tonteria *t)
{
printf("[%c , %02d , %3.1f]\n", t->c , t->x , t->y);
}
#ifndef ADT_BINTREE_H
#define ADT_BINTREE_H
#include <stdlib.h>
#include <string.h>
#include "ADTqueue.h"
#ifndef ADT_BINTREE_FLAGS
#define ADT_BINTREE_FLAGS
#define ADT_BINTREE_OK 0L
#define ADT_BINTREE_NOT_ENOUGH_MEMORY 1L
#define ADT_BINTREE_EMPTY_BINTREE 2L
#define ADT_BINTREE_ITEM_NOT_FOUND 4L
#define ADT_BINTREE_DUPLICATED_ITEM 8L
#endif /* ADT_BINTREE_FLAGS */
struct ADTBinTreeNode
{
void *Data;
struct ADTBinTreeNode* Left;
struct ADTBinTreeNode* Right;
};
typedef struct ADTBinTreeNode ADTBinTreeNode;
typedef ADTBinTreeNode ADTBinTree;
typedef ADTBinTreeNode* pADTBinTreeNode;
/* inicializa a cero la estructura para que funcine correctamente cuando sea utilizada */
void ADTBinTreeNodeIni(pADTBinTreeNode pNode);
/* determina si el arbol esta vacio */
int ADTBinTreeIsEmpty(pADTBinTreeNode Root);
/* insterta un nuevo dato en el arbol, eliminando duplicados de forma automatica */
unsigned long
ADTBinTreeInsert(pADTBinTreeNode *Root, void *data, void *key, size_t size, int (*cmp)(void*,void*));
/* elimina un dato del arbol */
unsigned long
ADTBinTreeDelete(pADTBinTreeNode *Root, void *data, void *key, size_t size, int (*cmp)(void*,void*));
/* busca a traves del campo clave key un elemento del arbol, guarda la info en data y devuelve un
puntero al dato encontrado si existe, en caso contrario devuelve NULL */
void* ADTBinTreeSearch(pADTBinTreeNode *Root, void *data, void *key, int (*cmp)(void*,void*));
/* libera la memoria ocupada por el arbol y la pasa a una cola, que es mas facil de liberar */
unsigned long ADTBinTreeDestroy(pADTBinTreeNode *Root, size_t dataSize , ADTQueueNode *pQueue);
/* recorrido en orden del arbol. Los datos se almacenan en la cola *pQueue */
unsigned long ADTBinTreeInOrder(ADTBinTreeNode* Root,size_t dataSize,ADTQueueNode* pQueue);
/* recorrido preorden del arbol. Los datos se almacenan en la cola *pQueue */
unsigned long ADTBinTreePreOrder(ADTBinTreeNode* Root,size_t dataSize,ADTQueueNode* pQueue);
/* recorrido post orden del arbol. Los datos se almacenan en la cola *pQueue */
unsigned long ADTBinTreePostOrder(ADTBinTreeNode* Root,size_t dataSize,ADTQueueNode* pQueue);
/* recorrido por niveles del arbol. Los datos se almacenan en la cola *pQueue */
unsigned long ADTBinTreeLevelOrder(ADTBinTreeNode* Root,size_t dataSize,ADTQueueNode* pQueue);
#endif /* ADT_BINTREE_H */
*/
), para poder seguir el codigo maquina hasta el punto en el que se leen los datos, a partir de ahi deberas investigar sobre donde se almacenan los datos y como se manipulan para obtener el pass correcto. Una vez que tengas claro como se manipulan los datos, lo unico que tienes que hacer es rehacer/deshacer los pasos para poder generar tu propia clave.