eliminar ancestros de hojas arbol binario c++

Iniciado por Lain SEL, 15 Agosto 2010, 20:47 PM

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

Lain SEL

Hola, estoy teniendo problemas a la hora de implementar ese método...
Se supone que tengo un arbol por ejemplo

                 50
       40               70

35                    65

se supone que si aplico el método, el arbol quedaría así:

            50
     35        65

estaba intentando hacer algo así

hacer un método que sacara los ancestros:

Código (cpp) [Seleccionar]
 TNodoABB *Arbol::ancestros(TNodoABB *arbol,int d)
{
TNodoABB *x;
 if(arbol!=NULL)
 {
     if(d < arbol->getInfo())
         x = ancestros(arbol->getIzq(),d);
     else if(d>arbol->getInfo())
         x = ancestros(arbol->getDer(),d);

     return x;
 }
 else return NULL;
}


ya lo probé y sí funciona luego cuando hago el eliminar se me cae :P ...

este es uno de mis intentos

bool Arbol::EliminarAncestros(TNodoABB *&A){
   if( A == NULL)
       return false;
   else
       if(Hoja(A) != NULL)
          return EliminarNodo(ancestros(Hoja(A),Hoja(A)->getInfo()));
       else
       {
       EliminarAncestros(Hoja(A->getIzq()));
       EliminarAncestros(Hoja(A->getDer()));
       return true;
       }

}


x.x pero aún no lo logro....

si alguien fuese tan amable de darme una luz acerca de como hacerlo se lo agradecería  :-*


Lh: No hagas doble post, utiliza el botón modificar. Utiliza la etiqueta GeSHi para poner código.


ya lo logré :D
wiiiii jijiji  ;D
acá les dejó el código para cuando alguien lo ocupe :)

Código (cpp) [Seleccionar]

bool Arbol::EliminarAncestros(TNodoABB *&A){
   TNodoABB *aux;
   int dato;

     if(A->getIzq() == NULL && A->getDer() != NULL && A->getDer()->getDer() == NULL) //si no tiene descendencia izquierda
     {                       //apunto al nodo a eliminar
       aux = A;              //redefino el arbol sin nodo a eliminar
       A = A->getDer();
       delete aux;
       return true;
     }
     else
     {
       if(A->getDer() == NULL && A->getIzq()->getIzq() == NULL) //tiene no tiene descendencia derecha
       {
           aux = A;
           A = A->getIzq();
           delete aux;
           return true;
       }
       else{//el nodo tiene dos descendencias
       if(A->getDer()->getDer() == NULL &&  A->getIzq()->getIzq() == NULL){
        dato = Mayor(A->getIzq());
        A->setInfo(dato);
        return Eliminar(dato, A->getIzq());
        }

        else{
         EliminarAncestros(A->getIzq());
         EliminarAncestros(A->getDer());
         return true;
        }
     }

     }



}



gracias :D .. lo tomaré en cuenta :)

Tha_Traker

#1
Por si te interesa esto es un programita de manejo básico de arboles binarios. Es una chorrada pero esta bien para entender el manejo y la estructura.

En mi humilde opinión, me parece que eso de poner 8 return es un desfase. Mucho más facil es usar un doble puntero, porque esa función es pequeña pero me pones una fucnión de 300 lineas con 20 return y ni me leo el código. Algnos diran que soy un purista pesado, pero digo yo que si se creo la programación estructurada no sería para decorar o por aburrimiento.
Otra cosa es que los // o /* */ sirve para poner comentarios, una cosa que la gente agradece cuando el programa no es suyo.

Un saludo


//Cabeceres de precompilación o librerias
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//Estructuras globales
typedef struct arbol{
char DNI[10];
char Nombre[20];
float nota;
struct arbol *izq;
struct arbol *der;
}T_ARBOL;




//Funciones
void Menu (int *op);
void Crear_nodo (T_ARBOL **nodo,T_ARBOL Dato);
void Insertar_nodo (T_ARBOL **nodo,T_ARBOL Dato);
void Limpiar_cadena (char *cadena, int n);
void visualizar (T_ARBOL *nodo);
void preorden (T_ARBOL *nodo);
void inorden (T_ARBOL *nodo);
void postorden (T_ARBOL *nodo);
T_ARBOL *Buscar(T_ARBOL *nodo,char *clave,T_ARBOL **POS);
void Eliminar_nodo (T_ARBOL **nodo,char *clave);
void Desconectar12 (T_ARBOL **nodo,T_ARBOL *POS,T_ARBOL **PAD);
void Desconectar3 (T_ARBOL **nodo,T_ARBOL *POS,T_ARBOL **PAD);

/*************************************************
********************PRINCIPAL*********************
*************************************************/
int main(void)
{
//ENTORNO
int op;
T_ARBOL *raiz;
T_ARBOL Info;
char clave[20];

//INICIALIZACIONES
raiz=NULL;
op=0;

//ALGORITMO

system("title Practica 8: Arboles");


do{
printf("\n ");
system("pause");
system("cls");
Menu(&op);

system("cls");

switch(op)
{
case 1://Introducir alumno
printf("\t\n Nombre: ");
fflush(stdin);    
fgets(Info.Nombre,20,stdin);
Limpiar_cadena(Info.Nombre,20);
printf("\t\n DNI: ");
fflush(stdin);    
fgets(Info.DNI,10,stdin);
Limpiar_cadena(Info.DNI,10);
printf("\t\n Nota: ");
scanf("%f",&Info.nota);


Insertar_nodo(&raiz,Info);


break;
case 2://Eliminar alumno

if(raiz!=NULL)
{
printf("\t\n Introduzca el nombre del alumno a borrar: ");
fflush(stdin);    
fgets(clave,20,stdin);
Limpiar_cadena(clave,20);

Eliminar_nodo(&raiz,clave);
}
else
{
printf("\t\n El arbol est%c vac%co",160,161);
}


break;
case 3://Preorden
if(raiz!=NULL)
{
preorden(raiz);
}
else
{
printf("\t\n El arbol est%c vac%co",160,161);
}
break;
case 4://Inorden
if(raiz!=NULL)
{
inorden(raiz);
}
else
{
printf("\t\n El arbol est%c vac%co",160,161);
}
break;
case 5://Postorden
if(raiz!=NULL)
{
postorden(raiz);
}
else
{
printf("\t\n El arbol est%c vac%co",160,161);
}
break;
case 6://Salir
printf("\t\n Gracias por usar este programa ");

break;

}//Fin Switch
}while(op!=6);

// Valor devuelto por el programa en caso de funcionamiento correcto.
return(0);
}
/*************************************************
********************FUNCIONES ********************
*************************************************/
void Menu(int *op)
{
do{
printf("\t\n  *** GESTI%cN DE NOTAS DE ALUMNOS ",162);
printf("\t\n1.A%cadir alumno(nodo) ",164);
printf("\t\n2.Eliminar alumno(nodo) ");
printf("\t\n3.Mostrar datos de alumnos en preorden ");
printf("\t\n4.Mostrar datos de alumnos en inorden ");
printf("\t\n5.Mostrar datos de alumnos en posorden ");
printf("\t\n6.Salir ");
printf("\t\n     Opci%cn: ",162);
scanf("%d",&*op);
}while(*op>6);

return;
}



//CREACIÓN DE UN NODO

void Crear_nodo(T_ARBOL **nodo,T_ARBOL Dato)
{
//ENTORNO

//ALGORITMO

//Pedir memoria
(*nodo)=(T_ARBOL*)calloc(1,sizeof(T_ARBOL));
if((*nodo)==NULL)//Control de errores
{
printf("\n\t Error al pedir memoria ");
}
else
{

//Copiar datos al elemento
strcpy((*nodo)->Nombre,Dato.Nombre);
strcpy((*nodo)->DNI,Dato.DNI);
(*nodo)->nota=Dato.nota;

//Crearmos los punteros a futuros hijos
(*nodo)->izq=NULL;
(*nodo)->der=NULL;


}
return;
}

//INSERTAR RECURSIVA

void Insertar_nodo(T_ARBOL **nodo,T_ARBOL Dato)
{

if(*nodo==NULL)
{
Crear_nodo(&(*nodo),Dato);

}
else
{
if(strcmp((*nodo)->Nombre,Dato.Nombre)==0)
{
printf("\t\n El elemento ya existe ");
}
else
{
if(strcmp((*nodo)->Nombre,Dato.Nombre)>0)//Izquierda
{
Insertar_nodo(&(*nodo)->izq,Dato);
}
else//Derecha
{
Insertar_nodo(&(*nodo)->der,Dato);
}
}
}
return;
}

void visualizar(T_ARBOL *nodo)
{
printf("\t\n ");
printf(" Nombre: ");
puts(nodo->Nombre);
printf(" DNI: ");
puts(nodo->DNI);
printf(" Nota: %f ",nodo->nota);
printf("\t\n ");
return;
}

void preorden(T_ARBOL *nodo)
{
 if (nodo != NULL) {
   visualizar(nodo);
   preorden(nodo->izq);
   preorden(nodo->der);
 }
}

void inorden(T_ARBOL *nodo)
{
 if (nodo != NULL) {
   inorden(nodo->izq);
   visualizar(nodo);
   inorden(nodo->der);
 }
}

void postorden(T_ARBOL *nodo)
{
 if (nodo != NULL) {
   postorden(nodo->izq);
   postorden(nodo->der);
   visualizar(nodo);
 }
}



T_ARBOL *Buscar(T_ARBOL *nodo,char *clave,T_ARBOL **PAD)
{
//ENTORNO
T_ARBOL *POS;
int sw;


//INICIALIZACIONES
POS=nodo;
PAD=NULL;
sw=0;
//ALGORITMO
while(sw!=1 && POS!=NULL)
{
//Encontrado
if(strcmp(POS->Nombre,clave)==0)
{
sw=1;
}
//Seguimos buscando
else
{
(*PAD)=POS;
if(strcmp(POS->Nombre,clave)<0)
POS=POS->der;
else
POS=POS->izq;
}
}

return(POS);
}


void Eliminar_nodo(T_ARBOL **nodo,char *clave)
{
T_ARBOL *PAD;
T_ARBOL *POS;

//Buscar el elemento a borrar
POS=Buscar((*nodo),clave,&PAD);
if(POS==NULL)
printf("\n No encontrado");
else
{
//En caso de que tenga 2 hijos
if(POS->izq!=NULL && POS->der!=NULL)
{
Desconectar3(&(*nodo),POS,&PAD);
}
//Si no tiene o solo tiene 1 hijo.
else
{
Desconectar12(&(*nodo),POS,&PAD);
}
//Liberamos la memoria
free(POS);
}
return;
}

void Desconectar12(T_ARBOL **nodo,T_ARBOL *POS,T_ARBOL **PAD)
{

T_ARBOL *HIJO;

//No tiene hijos
if(POS->izq==NULL && POS->der==NULL)
{
HIJO=NULL;
}
//Tiene 1 hijo
else
{
if(POS->izq==NULL)
HIJO=POS->der;
else
HIJO=POS->izq;
}
//El nodo a eliminar es la raiz
if((*PAD)==NULL)
{
*nodo=HIJO;
}
else
{
if(POS==(*PAD)->izq)//ERROR
(*PAD)->izq=HIJO;
else
(*PAD)->der=HIJO;

}



return;
}

void Desconectar3(T_ARBOL **nodo,T_ARBOL *POS,T_ARBOL **PAD)
{
//ENTORNO
T_ARBOL *SIG;
T_ARBOL *PADSIG;

//INICIALIZACIONES
PADSIG=POS;
SIG=POS->der;
//ALGORITMO
//Buscar el siguiente en INORDEN
while(SIG->izq !=NULL)
{
PADSIG=SIG;
SIG=SIG->izq;
}
//Desconectarlo
Desconectar12(&(*nodo),SIG,&PADSIG);
//Borrarlo
if(PAD==NULL)
(*nodo)=SIG;
else
{
if(POS==(*PAD)->izq)
(*PAD)->izq=SIG;
else
(*PAD)->der=SIG;
}
SIG->izq=POS->izq;
SIG->der=POS->der;

return;
}


void Limpiar_cadena(char *cadena, int n)
{
   // Variable local.
   int i;
   
   // Sustituimos el \n por un \0.
   i=0;
   while(cadena[i]!='\n' && i<n-1)
   {
       i++;
   }
   cadena[i]='\0';
       
   
   return;
}



Lain SEL

sip, eres pesado.. pero gracias  ;D cierto me faltaron más comentarios pero si puse y conozco el uso de //
/**/  :silbar: