Buenas.
Este es un ejercicio que me tomaron en un exámen reciente de la facultad y quería saber si lo que hice está bien o no.
Les paso el ejercicio completo que hice para darles una idea de qué es y al final hago mi pregunta concreta.
El ejercicio consiste en hacer una fc. que espeje un árbol. Es decir. Si el árbol A tiene en la raíz un 1, en el hijo izquierdo un 2 y en el derecho un 3, el nuevo árbol B tendrá que tener raíz 1, hijo izquierdo 3 e hijo derecho 2. Así con todos los elementos.
typedef struct TNodo
{
void *elem;
struct TNodo *Izq,*Der;
} TNodo;
typedef struct
{
TNodo *Raiz, Corriente;
int tamaniodato;
}TDA_AB;
int ABO_Espejar (TDA_AB A, TDA_AB *B)
{
int memoria;
if !(A.Raiz) return 0;//Arbol A vacío.
if (B.Raiz) return 1; //Arbol B ya cargado.
if !(memcpy(A.Raiz->elem,B.Raiz->elem,A.tamaniodato)) return 2;//mem. insuf.
Recursiva(A.Raiz,B.Raiz,A.tamaniodato,&memoria);
return(memoria);//Si memoria=2 falta memoria. Si memoria=3 está todo OK.
}
/*memcpy copia elementos void. Del 1º campo copia al 2º y ocupa lo que dice el
3º campo. ABO_Espejar consiste en: Dan un árbol binario A y los elementos de A
se copian en B pero en forma de espejo. Es decir: el hijo izq de la raiz de A
queda como hijo der de la raiz de B... y así. Copia la raiz de A en la raiz de B
luego llama a recursiva. ABO_Espejar retorna el valor de "memoria"*/
int Recursiva (TNodo *PNodo, TNodo *Otro, int dato, int *memoria)
{
if (PNodo->Izq)
{
if !(memcpy(PNodo->Izq->elem,Otro->Der->elem,dato)) memoria=2;
Recursiva (PNodo->Izq,Otro->Der,dato,memoria);
}
if (PNodo->Der)
{
if !(memcpy(PNodo->Der->elem,Otro->Izq->elem,dato)) memoria=2;
Recursiva(PNodo->Der,Otro->Izq,dato,memoria);
}
}
/*Verifica que haya nodo en la izquierda en el árbol A. Si lo hay, copia el
elemento en la derecha del árbol B (si no puede copiar memoria toma el valor 2).
Luego llama a la misma función recursiva yendo al nodo izquierdo del árbol A y
al nodo derecho (recientemente copiado) del árbol B. Lo mismo realiza en el
nodo derecho.*/
Bueno... acá va mi duda:
Yo tengo que copiar (con el ejemplo que dí anteriormente) un elemento de A y pegarlo en B. Si yo uso esa fc. memcpy estoy copiando el elemento en, por ejemplo, Otro->Izq->elem... Eso de copiar el elemento en ese nodo está ok (yo estoy accediendo al elemento a que apunta ese nodo), pero ese nodo existe? Se puede ingresar a ese nodo de esa forma? Porque (no sé bien esta parte) Otro->Izq apunta (o es) NULL. Entonces mi otra forma (que esto NO hice en el exámen) era copiar el nodo de la forma: Otro->Izq=PNodo->Der y así, a la vez, se copiarán los elementos (creo). El único problema de esto es que el árbol seguramente puede ser muy grande, y yo le estaría pasando mucha información incorrecta y de más al árbol B (y sólo quiero pasarle el nodo en cuestión y que no apunte a ningún otro). Es decir... si estoy copiando el nº 3 (como el ejemplo que dí), si el nº 3 del árbol A tuviese otros hijos (u hojas) estaría copiándoselas a B también.
Mmmmmmmmm... no sé si se entiendió o no, pero ya me mareo =D
Otra cosa que tiene mucho que ver con esto, pero que sería como "a parte" es:
yo uso cosas como "if !(PNodo->Izq)" y realmente no sé bien por qué se usa así... pero sé que quiere decir que "si no existe PNodo-Izq...". si pasa que no existe PNodo->Izq es que está apuntando a NULL? O sea PNodo->Izq == NULL? Y si PNodo-Izq existe, a qué apunta? O sea... PNodo->Izq == ¿a qué? :S
Espero que puedan ayudarme ya que es una de las cosas que me faltan entender por si me fue mal :D
Desde ya, muchas gracias!
PD: Perdón por tantas preguntas, pero esta parte es algo que no me quedó claro y me gustaría entenderla.