¿Mejor algoritmo? Problema con aproximaciones de Grafos

Iniciado por KINGARZA, 27 Julio 2016, 09:43 AM

0 Miembros y 1 Visitante están viendo este tema.

KINGARZA

Hola que tal a todos!!
llevo horas quemandome la cabeza y aun no encuetro una solucion optima para este problema, podras ayudarme? te lo agradeceria mucho.

este es el problema:
Amigos Interactivos

      Límite de memoria   128MB
               Límite de tiempo (caso)   1s   
               Límite de tiempo (total)   60s
Existe una serie de personas definidas en un espacio, dichas personas tienen la capacidad nata de comuncarse entre ellas y formar relaciones sociales, sin embargo hay relaciones muy especiales que dicen llamarce amistad, dichos individuos son conciderados amigos si realizan algun tipo de saludo especial. Una empresa de analisis de comportamiento humano te ha pedido que les ayudes a saber si un individuo A es amigo de un individuo B., un dato curioso es que si existen tres invidividuos A, C, B pertenecientes al espacio, y A es amigo de C y C amigo de B, se genera un lazo mistico mediante el cual A y B son amigos, aunque pudieren no conocerse.

Problema

Dada una descripcion de los sucesos que existen durante la estancia de N individuos en un espacio definido, responder secuencialmente a las preguntas fornuladas, de manera tal que se sepa si en algun momento un indiviuo es amigo del otro.

Entrada

Un unico numero N indicando la cantidad de Individuos

Un numero M indicando la cantidad de preguntas o sucesos que acontecen

Las siguientes M lineas contendran una letra 'P' seguida de dos enteros A y B de tal modo que se debera saber si A es amigo de B en base a los saludos que hallan sido registrados hasta el momento, en caso contrario, una letra 'S' seguida de dos numero A y B indicando que el individuo Ase ha saludado con el individuo B

Ejemplo:
Entrada   Salida
5 8  
S 1 2  
S 2 3  
P 2 4  
S 4 5  
P 5 3  
S 5 1  
P 2 4  
P 5 3
Salida

Un numero en una linea por cada pregunta dada en la entrada con un 1 si es que son amigos y un cero en caso contrario

Ejemplo:
Entrada   Salida
0  
0  
1  
1
Límites

0< N < 100,000

0<M < 100,000

por el momento lo que llevo pensado es lo siguiente:
crear un array del tamaño de los amigos donde ese array almacenara vectores.
ahora como en el ejemplo meten un saludo de las personas 1 y 2.
en el vector de la persona 1 meto el 2
en el vector de la persona 2 meto el 1
con esto se que ambos se conocen.
ahora meten un salud de las personas 2 y 3.
hago lo mismo que arriba pero si nos damos cuenta tambien deben conocerse 1 y 3 asi que debo hacer algo mas.
aqui segun yo lo complicado:
         hago un for que recorra los amigos amigos de "a" donde a cada amigo de "a"
         le agrego un amigo de "a" que no tenga (por el lazo misterioso que mencionan        en el el problema)
por ejemplo:
en este caso el amigo a es 2 que tiene de amigos 1 y 3.
recorro el 2 llego al 1 y checo es amigo de 3 ? no, entonces añadelo
ahora llego al tres y checo es amigo de 1 ? no, entonces añadelo
bueno eso es todo lo que llevo ahora el codigo, que aun no acabo mi idea por lo que les mencione arriba:
Código (cpp) [Seleccionar]
#include<bits/stdc++.h>
using namespace std;
typedef struct arrays{
   vector<int>amigos;
}persona;
int main(){    
   bool encontrado;
   char opcion;
   int individuos, preguntas, a, b;
   int i, j, k, l;
   cin>>individuos>>preguntas;
   persona ar[individuos + 1];
   for(i = 0; i < preguntas; i++){
       cin>>opcion>>a>>b;
       if(opcion == 'S'){
           ar[a].amigos.push_back(b);
           ar[b].amigos.push_back(a);
           for(j = 1; j < ar[a].amigos.size(); j++)                
               for(k = j + 1; k < ar[a].amigos.size() + 1; k++)
                   for(l = 0; l < ar[j].amigos.size(); l++)
                       
                                       
       }
       else{

       }
   }
   return 0;
}

si se les ocurre una idea mejor a la mia por favor!! avisenme!!!

AlbertoBSD

#1
CitarUna empresa de analisis de comportamiento humano
a.k.a Facebook
:silbar: :silbar:

CitarPERO SI NOS DAMOS CUENTA TAMBIEN DEBEN CONOCERSE 1 Y 3 ASI QUE DEBO HACER ALGO MAS.

A lo qu yo entendi esto no es asi, a no ser que este mal redactado o mal traducido. Ya que con solo unir un conjunto de elementos con otros tendrias que agregar todos y cada uno de los elementos a todos los elementos del otro conjunto y viceversa.

Lo que entiendo es que una vez que los vas dando de alta y te pregunten por A o B tu  veas si en ese momento se cumple esa relacion "magica" de amistad.

Pero en cualquiera de los casos, Ya sea de la forma en la que tu lo piensas o yo lo estoy pensando. En Ambos se resuelve con un GRAFO.

En tu caso solo es necesario saber si existe una ruta del nodo A al nodo B

y en mi caso si existe y si su profundidad es de al menos 2

Dado que te imponen tiempos y limite de memoria el problema se trata de complejidad de algoritmo...

Se puede resolver usando un Grafo. Se llena un grafo con los saludos y cuando pregunten por X relacion hay que buscar en el grafo si existe un camino del individuo A a B y si es asi evaluar la ruta mas corta si el numero de saltos o nodos entre A y B es menor o igual a 2.

Si esto es asi entonces A y B son amigos.

Tienes que usar el algoritmo de disjktra.

Saludos



Edito acabo de realizar el programa usando una simplicacion de grafos y búsqueda pero tengo una duda.
CitarUn numero en una linea por cada pregunta dada en la entrada con un 1 si es que son amigos y un cero en caso contrario

Ejemplo:
Entrada   Salida
0  
0  
1  
1
Límites

Es la  salida de tu primer ejemplo?

Ya que no veo como puede estar conectado 2 con 4 o el ultimo caso 5 con 3 (usando solo un conocido en comun)

por cierto el principal problema es la busqueda de la relacion entre los individuos (nodos)
ya que si el peor de los casos tiene 100,000 entradas ai lo buscas iterarivamente 100000 veces vas a tardar mas de 1 segundo por caso.

Mi recomendacion seria combinar alguna otra forma de busqueda mas rapida por ejemplo arboles binarios.

En lo que llegue a mi trabajo pego el codigo.

Saludos




Edito nuevamente (Estos ejercicios me gustan mucho)

Recomiendo generar una entrada que realmente estrese el procesador

Hice este codigo que genera el maximo de 100,000 inputs al azar

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define MAX 100000

int main() {
register int i = 0;
srand(time(NULL));
printf("%i %i\n",MAX,MAX);
while(i < MAX) {
printf("%c ",(rand()%2) ? 'P':'S');
printf("%i %i\n",1+ rand()%MAX,1+ rand()%MAX);
i++;
}
}


Y con ese entrada, mi codigo encuentra todas las posibilidades en 1.08 segundos.

La solución que use como les comente es un arbol y búsqueda binaria entre nodos individuales.


No pongo el código del programa por si hay algún otro interesado no afectar su programación.

Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

KINGARZA

#2
muchísimas gracias alberto por responder!!
explicare la salida:
lo primero ya lo dije la relación de 1, 2 y 3.
preguntan 2 conoce a 4 ? no, porque ni siquiera se ha mencionado a 4.
luego preguntan por 5 y 3 como 5 solo es amigo de 4 no hay ninguna relacion asi que no son amigos.
ahora se saludan 4 y 5 esto es como el primer caso donde se saludan 1 y 2.
por ultimo se saludan 5 y 1, aqui la magia, todos los amigos de 1 serán amigos de 5, y como vimos 4 es amigo de 5, asi que todos los amigos de 5 seran amigos de 4, entonces por eso queda la salida queda asi:

0
0
1
1

y si nos damos cuenta al final todos se conocen  :o
mira este el link del problema es un juez en linea https://omegaup.com/arena/problem/am#problems

también gracias por el código lo usare una vez que acabe mi programa.
si alguien puede resolverlo por favor comparta su respuesta, yo si lo acabo lo compartiré.
un saludo!!.




oye y respecto a la implementacion:
¿se puede usar un arbol binario de prioridades?
(priority binary tree)


engel lex

Mod: Lee las reglas del foro y sigue las advertencias!

No escribas en mayúsculas (corregido)
los titulos de los temas deben ser descriptivos!
no hagas doble post!

antes de responder a este tema nuevamente corrige el titulo
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

AlbertoBSD

#4
Pues a mi me parece algo incorrecta la forma de interpretar la lectura ya que ahi hablan de solo u  amigo en comun.
Citarun dato curioso es que si existen tres invidividuos A, C, B pertenecientes al espacio, y A es amigo de C y C amigo de B, se genera un lazo mistico mediante el cual A y B son amigos,

Y la implementacion esta hablando del amigo del amigo del amigo.

EN FIN...

La implementacion podria ser cualquier arbol binario para optimizar las busquedas aunque el hecho de tener un arbol por individuo usa mucha memoria.

En minuto mas pongo mi implementacion ( La cual solo aborda el primer ejemplo que yo dije donde solo valido a los amigos del primer amigo)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdbool.h>

#define MAXLINE 40

struct nodo_arbol {
struct nodo_arbol *padre,*derecho,*izquierdo;
int valor;
};

struct nodo {
int id;
int *relations;
int total;
struct nodo_arbol *arbol;
};

struct nodo **todos = NULL; //Futuro arreglo de todos los nodos existente

void add_relation(int A,int B);
bool existe_salto(int A,int B);

struct nodo_arbol *crear_nodo_arbol(struct nodo_arbol *padre,int valor);
struct nodo_arbol *buscar_nodo_arbol(struct nodo_arbol *arbol,int valorAbuscar);
struct nodo_arbol *agregar_valor_arbol(struct nodo_arbol *arbol,int valor);


int main() {
FILE *in = NULL;
char *line = NULL;
char *delim = " \n";
char *token;
char caso;
int N,M,i,A,B;
in = fopen("amistad.in","r");
line = calloc(MAXLINE,1);
fgets(line,MAXLINE,in);
token = strtok(line,delim);
N = strtol(token,NULL,10);
todos = calloc(sizeof(struct nodo*),N); //Reservamos espacio para al menos N apuntadores a los nodos
token = strtok(NULL,delim);
M = strtol(token,NULL,10);
i = 0;
while(i < M) {
memset(line,0,MAXLINE);
fgets(line,MAXLINE,in);
token = strtok(line,delim);
caso = token[0];
token = strtok(NULL,delim);
A = strtol(token,NULL,10);
A--;
token = strtok(NULL,delim);
B = strtol(token,NULL,10);
B--;
switch(caso){
case 'P':
//printf("P %i %i\n",A+1,B+1);
if(todos[A] && todos[B]) { // Ambos nodos son Validos, entonces hay que buscar si existe al menos un camino de a A a B
if(existe_salto(A,B)) {
printf("1\n");
}
else {
printf("0\n");
}
}
else { // Uno de los nodos es NULL entonces no existe camino de A a B
//printf("Un nodo es invalido\n");
printf("0\n");
}
break;
case 'S':
//printf("S %i %i\n",A+1,B+1);
add_relation(A,B);
break;
}
i++;
}
fclose(in);
return 0;
}

void add_relation(int A,int B) {
if(todos[A] != NULL) {
//Nodo ya inicializado;
todos[A]->relations = realloc(todos[A]->relations,sizeof(int)*(todos[A]->total+1));
todos[A]->relations[todos[A]->total] = B;
todos[A]->arbol = agregar_valor_arbol(todos[A]->arbol,B);
todos[A]->total++; //incrementamos el numero total de relaciones que tiene este nodo
}
else {
//Nodo no inicializado
todos[A] = calloc(sizeof(struct nodo),1);
todos[A]->id  = A; //Esto es mera formalidad, ya que actualmente el indice del arreglo ya es el mismo "id"
todos[A]->relations = realloc(todos[A]->relations,sizeof(int)*(todos[A]->total+1));
todos[A]->relations[todos[A]->total] = B;
todos[A]->arbol = agregar_valor_arbol(todos[A]->arbol,B);
todos[A]->total++; //incrementamos el numero total de relaciones que tiene este nodo
}
if(todos[B] != NULL) {
//Nodo ya inicializado;
todos[B]->relations = realloc(todos[B]->relations,sizeof(int)*(todos[B]->total+1));
todos[B]->relations[todos[B]->total] = A;
todos[B]->arbol = agregar_valor_arbol(todos[B]->arbol,A);
todos[B]->total++; //incrementamos el numero total de relaciones que tiene este nodo
}
else {
//Nodo no inicializado
todos[B] = calloc(sizeof(struct nodo),1);
todos[B]->id  = B; //Esto es mera formalidad, ya que actualmente el indice del arreglo ya es el mismo "id"
todos[B]->relations = realloc(todos[B]->relations,sizeof(int)*(todos[B]->total+1));
todos[B]->relations[todos[B]->total] = A;
todos[B]->arbol = agregar_valor_arbol(todos[B]->arbol,A);
todos[B]->total++; //incrementamos el numero total de relaciones que tiene este nodo

}
}

bool existe_salto(int A,int B) {
bool r = false;
struct nodo *nodo_a = NULL,*nodo_b =NULL,*inicio =NULL,*pivote = NULL;
struct nodo_arbol *busqueda = NULL;
register int i,j,buscar;
nodo_a = todos[A];
nodo_b = todos[B];
if(nodo_a->total < nodo_b->total) {
//printf("Menor A %i\n",A+1);
inicio = nodo_a;
buscar = B;
}
else {
//printf("Menor B %i\n",B+1);
inicio = nodo_b;
buscar = A;
}
i = 0;
//printf("Nodos: ");
while(i < inicio->total && !r) {
//printf("%i\t ",inicio->relations[i]+1);
busqueda = buscar_nodo_arbol(inicio->arbol,buscar);
if(busqueda) {
r = true;
}
i++;
}
//printf("\n");
if(!r) {
i = 0;
while(i < inicio->total && !r) {
pivote = todos[inicio->relations[i]];
j = 0;
//printf("Nodos de %i:  ",inicio->relations[i]+1);
while(j < pivote->total && !r) {
busqueda = buscar_nodo_arbol(pivote->arbol,buscar);
//printf("%i\t ",pivote->relations[j]+1);
if(busqueda) {
r = true;
}
j++;
}
//printf("\n");
i++;
}
}
return r;
}


struct nodo_arbol *crear_nodo_arbol(struct nodo_arbol *padre,int valor) {
struct nodo_arbol *n = calloc(sizeof(struct nodo_arbol),1);
if(n == NULL) {
printf("Error de Memoria\n");
exit(0);
}
n->padre = padre;
n->valor = valor;
return n;
}

struct nodo_arbol *agregar_valor_arbol(struct nodo_arbol *arbol,int valor) {
struct nodo_arbol *temp,*pivote;
int derecho = 0;
if(arbol) {
temp =arbol;
while(temp != NULL) {
pivote = temp;
if(valor > temp->valor) {
temp = temp->derecho;
derecho = 1;
}
else {
temp = temp->izquierdo;
derecho = 0;
}
}
temp = crear_nodo_arbol(pivote,valor);
if(derecho) {
pivote->derecho = temp;
}
else {
pivote->izquierdo = temp;
}
return arbol;
}
else {
temp = crear_nodo_arbol(NULL,valor);
return temp;
}
}

struct nodo_arbol *buscar_nodo_arbol(struct nodo_arbol *arbol,int valorAbuscar) {
struct nodo_arbol *temp = NULL,*pivote = NULL;
int entrar = 1;
temp =arbol;
while(entrar == 1  && temp != NULL) {
pivote = temp;
if(valorAbuscar == temp->valor){
entrar = 0;
}
else {
if(valorAbuscar > temp->valor) {
temp = temp->derecho;
}
else {
temp = temp->izquierdo;
}
}
}
return temp;
}


Solo habria que extenderla para que revise todos los nodos.

Saludoa
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

engel lex

El titulo debe ser Descriptivo, te explico

CitarPropuestas para resolver problema en C++

Describe tanto el tema como

CitarNecesito tu ayuda para resolver un problema en C++

Es decir, no lo describe...
CitarDescribir
verbo transitivo
1.
Explicar cómo es una cosa, una persona o un lugar para ofrecer una imagen o una idea completa de ellos.
"en el manual se describen las principales especies animales que habitan en la zona; entonces aquella ciudad me pareció triste así la recuerdo y así la describo e impregnada de singular melancolía"
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

AlbertoBSD

Titulos sugeridos:

¿Mejor algoritmo? Problema con aproximaciones de Grafos

Optimizar algoritmo para busqueda de elementos

Saludos
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

KINGARZA

#7
Alberto muchas gracias por compartir tu respuesta y por la propuesta.
Mira la verdad no entiendo mucho el tema de los arboles binarios, solo he creado uno (hace 1 semama aprox.)y pues conozco muy pocas cosas, ademas de que usas cosas nuevas para mi como calloc, strtok , strtol, etc..
Pero me esforzare mucho en tratar de entenderlo.
En cuanto a mi, les comparto mi respuesta ya la envie a la pagina y me da estos resultados:
Status: Tiempo Limite Excedido.
Porcentaje: 90%.
Memoria: 48.98 MB.
Tiempo: >2.78 s.
Como ven es buena respuesta pues me da el 90%.
Y ahora explicare que fue lo que hice:
Después de buscar en internet me encontré con el set que es un contenedor asociativo que tiene la característica de no guardar valores repetidos y los guarda en orden.
entonces aqui reemplazaba los vectores por los sets.
ahora, lo mas complicado es donde se saludan lo explique anteriormente, ahora lo hare mejor:
se saluda 1 y 2.
en el set de 1 pongo el 2.
en el set de 2 pongo el 1.
ahora recorro el set de 1 y a los amigos de 1 les agregare los amigos de 1, lo mismo hago con el 2, pero como ambos sets tienen un solo elemento que son 1 y 2 respectivamente no pasa nada.
se saluda 2 y 3.
en el set de 2 pongo el 3.
en el set de 3 pongo el 2.
ahora recorro el set de 2 y a sus amigos les añado los amigos de 2.
lo mismo hago con el 3.
entonces hasta ahora los sets quedan asi:
persona:                 conocidos:
  1                              2,3
  2                              1,3
  3                              1,2
preguntan 2 conoce a 4 ?
checo, si cualquier set esta vacio (A o B)entonces quiere decir que no, pues no a saludado a nadie, sino recorro el set de la persona A y busco si esta la persona B.
en este caso es NO.
se saluda 4 y 5.
en el set de 4 pongo el 5.
en el set de 5 pongo el 4.
ahora recorro el set de 4 y a los amigos de 4 les agregare los amigos de 4, lo mismo hago con el 5, pero como ambos sets tienen un solo elemento que son 4 y 5 respectivamente no pasa nada.
entonces hasta ahora los sets quedan asi:
persona:                 conocidos:
  1                              2,3
  2                              1,3
  3                              1,2
  4                              5
  5                              4  
ahora preguntan 5 conoce a 3?
checo, si cualquier set esta vacio (A o B) entonces quiere decir que no, pues no a saludado a nadie, sino recorro el set de la persona A y busco si esta la persona B.
en este caso es NO.
Por ultimo se saluda 5 con 1.
en el set de 5 pongo el 1.
en el set de 1 pongo el 5.
ahora recorro el set de 5 y a todos sus amigos les añado los amigos que no tengan de 5, lo mismo hago con el 1 y si nos damos cuenta ya todos son amigos, por ende las siguientes preguntas son SI.
Aqui les dejo el codigo:
Código (cpp) [Seleccionar]
#include<bits/stdc++.h>
using namespace std;
                           /*DECLARO TODO LO QUE USARE DE SET Y EL VECTOR QUE GUARDARA LAS RESPUESTAS*/
typedef struct arrays{
   set<int>amigos;
}ar;
    set<int>::iterator j;
    set<int>::iterator k;
    vector<string>respuestas;

int main(){
   cin.tie(0);
   ios_base::sync_with_stdio(0);
   bool encontrado;
   char opcion;
   int personas, comandos, a, b;
   int i, l, z;
   cin>>personas>>comandos;

   ar persona[personas + 1]; /*CREAMOS UN ARRAY DE SETS DE TAMAÑO PERSONAS*/

   for(i = 0; i < comandos; i++){
       cin>>opcion>>a>>b;
       if(opcion == 'S'){
           persona[a].amigos.insert(b);
           persona[b].amigos.insert(a);
           for(j = persona[a].amigos.begin(); j != persona[a].amigos.end(); j++){ /* PERSONA A*/
               for(k = persona[a].amigos.begin(); k != persona[a].amigos.end(); k++){
                   persona[*j].amigos.insert(*k);
               }
           }
           for(j = persona[b].amigos.begin(); j != persona[b].amigos.end(); j++){ /*PERSONA B*/
               for(k = persona[b].amigos.begin(); k != persona[b].amigos.end(); k++){
                   persona[*j].amigos.insert(*k);
               }
           }
       }
       else{
           if(persona[a].amigos.empty() || persona[b].amigos.empty())
               respuestas.push_back("0\n");
           else{
               encontrado = false;
               for(j = persona[a].amigos.begin(); j != persona[a].amigos.end(); j++){/*BUSCAMOS SI EN LOS AMIGOS DE A ESTA B*/
                   if(*j == b){
                       encontrado = true;
                       break;
                   }
               }
               if(encontrado)
                   respuestas.push_back("1\n");
               else
                   respuestas.push_back("0\n");
           }
       }
   }
   for(i = 0; i < respuestas.size(); i++)
       cout<<respuestas[i];
   return 0;
}

Creo que si optimizamos la búsqueda de la persona B en A y al agregar amigos podría dar el 100%
Encontre en internet algo llamado set_union y merge para eso de añadir los amigos pero eso de buscar los amigos pensaba en una búsqueda binario aunque según yo que no es posible.

AlbertoBSD

#8
Hola.

Citarpensaba en una búsqueda binario aunque según yo que no es posible.

Los arboles binarios por su diseño implementan una busqueda binaria


Si lo quieres manejar manualmente en un array tendrias que ordenarlos para posteriormente hacer una búsqueda binaria.

Calcule la memoria que usaria mi codigo y seria cerca de 2 MB en el peor de los casos (100000) inputs.

hay veces que me complico programando en C ya que me gusta saber que hace exactamente el codigo. Lo que tu haces con un simple cin>>  yo lo hago como con 10 lineas de codigo y au que son muchas lineas siento que se ejecuta igual de rapido que un cin o incluso mas rapido aun...

Busca como implementar una busqueda binaria y el algoritmo de disjktra es lo mas rapido que vas a encontrar y terminarias usando menos memoria.

Voy a adaptar mi codigo a C++ para que veas como funciona.

Mientras te dejo unos videos que hice de arboles binarios

[youtube=640,360]https://www.youtube.com/watch?v=BBsgYwXGdI8[/youtube]

[youtube=640,360]https://www.youtube.com/watch?v=hlWvK1EU-oA[/youtube]

Saludos
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

KINGARZA

Alberto un pregunta en cuanto a tu video, como te comente ya habia hecho un arbol binario, pero yo en la estructura del nodo solo habia utilizado el dato y los dos punteros izquierdo y derecho, mi pregunta es ¿Para que sirve el nodo padre?
Bueno y otra duda, en tu arbol binario del problema quien es la raiz o como funciona eso de ir añadiendo nodos (disculpa mi ignorancia)?
Mira este es mi codigo:
Código (cpp) [Seleccionar]
#include <bits/stdc++.h>
using namespace std;

struct nodoArbol {
struct nodoArbol *ptrIzq;
int dato;
struct nodoArbol *prtDer;
};

typedef struct nodoArbol NodoArbol;
typedef NodoArbol *ptrNodoArbol;

void insertaNodo( ptrNodoArbol *ptrArbol, int valor ){

    if (*ptrArbol == NULL) { /*ARBOL VACIO*/
        *ptrArbol = (NodoArbol*)malloc(sizeof(NodoArbol));
        (*ptrArbol)->dato = valor;
        (*ptrArbol)->ptrIzq = NULL;
        (*ptrArbol)->prtDer = NULL;
    }

    else {
        /* el dato a insertar es menor que el dato en el nodo actual */
        if (valor < (*ptrArbol)->dato) {
            insertaNodo(&((*ptrArbol)->ptrIzq), valor);
        }
        else if (valor > (*ptrArbol)->dato) {
            insertaNodo(&((*ptrArbol)->prtDer), valor);
        }
    }
}

void inOrden(ptrNodoArbol ptrArbol){
    if (ptrArbol != NULL) {
        inOrden(ptrArbol->ptrIzq);
        cout<<ptrArbol -> dato<<" ";
        inOrden(ptrArbol->prtDer);
    }
}

void preOrden(ptrNodoArbol ptrArbol){
    if (ptrArbol != NULL){
        cout<<ptrArbol -> dato<<" ";
        preOrden(ptrArbol->ptrIzq);
        preOrden(ptrArbol->prtDer);
    }
}

void postOrden(ptrNodoArbol ptrArbol) {
    if (ptrArbol != NULL){
        postOrden(ptrArbol->ptrIzq);
        postOrden(ptrArbol->prtDer);
        cout<<ptrArbol -> dato<<" ";
    }
}

int main(){

    ptrNodoArbol ptrRaiz = NULL;
    int limite,elemento;
    cout<<"INTRODUCE CUANTOS ELEMENTOS TENDRA EL ARBOL: ";
    cin>>limite;

    for (int i = 1; i <= limite; i++) {
        cout<<"INGRESE ELEMENTO: ";
        cin>>elemento;
        insertaNodo(&ptrRaiz, elemento);
    }

    cout<<"\nEL RECORRIDO EN PREORDEN ES:\n";
    preOrden(ptrRaiz);

    cout<<"\nEL RECORRIDO EN INORDEN ES:\n";
    inOrden(ptrRaiz);

    cout<<"\nEL RECORRIDO EN POSTORDEN ES:\n";
    postOrden(ptrRaiz);

    return 0;
}

Gracias por tu ayuda.