Hola amigos!
tengo un problema intentando implementar una funcion remover, para un arbol binario de busqueda.
con un compañero planteamos este algoritmo:
 
arbol_t *removerDesbalanceado(arbol_t *arbol, int valor){ 
    arbol_t *aux;    
 
    if(!arbol) 
        return NULL;
 
    if(arbol->contenido > valor) 
        arbol->iz = removerDesbalanceado(arbol->iz,valor); 
    else if(arbol->contenido < valor) 
        arbol->der = removerDesbalanceado(arbol->der,valor); 
    else{   //Si es igual 
        if(arbol->der == NULL){ 
            if(arbol->iz == NULL) 
                return NULL;    //Si no tiene hijos retorna Null 
            return arbol->iz;   //sino retorna todo el subarbol izquierdo 
        } 
        else{ 
            aux = menor(arbol->der); 
            aux->iz = arbol->iz; 
            aux = arbol->der; 
            return aux; 
        } 
    } 
}
 
 
arbol_t es la estructura de un nodo con un campo contenido y dos campos punteros de hijos:
typedef struct arbolStr{ 
    int contenido; 
    struct arbolStr *iz, *der; 
}arbol_t;
 
le pusimos removerDesbalanceado pq lo que hacemos es una vez q encontramos el nodo a remover ponemos en lugar de este, todo el arbol derecho, enlazando el nodo de mas abajo a la iz (el de menor valor) con el arbol izquierdo del nodo a remover.
se lo mostramos a otro compañero y nos dijo, que el arbol se iba a desbalancear demaciado, y que lo mejor seria: agarrar el menor del hijo derecho del arbol a remover y poner el valor de ese nodo como el valor del nodo a remover y luego hacer que el que apuntaba al nodo del cual "robamos"  el valor apunte a NULL.
entonces el arbol quedaria mucho mas balanceado y la remocion seria mas efectiva.
nuestro problema es el de hacer que el nodo que apuntaba al nodo del "robamos" el valor apunte a null.
este es nuestro codigo, no terminado, en principio copiamos la funcion de removerDesbalanceado para modificarla, quiza hay cosas que son de la otra funcion y no estan modificadas:
arbol_t *removerBalanceado(arbol_t *arbol, int valor){ 
    arbol_t *a, *b; 
    int cont;    
 
    if(!arbol) 
        return NULL;    
 
    if(arbol->contenido > valor) 
        arbol->iz = removerBalanceado(arbol->iz,valor);  
    else if(arbol->contenido < valor)        
        arbol->der->contenido = removerBalanceado(arbol->der,valor); 
    else{       //Si es igual, osea, si encontre el nodo a remover 
        if(arbol->der == NULL){ 
            if(arbol->iz == NULL) 
                return NULL;        //Si no hay hijo iz ni der devuelvo null 
            return arbol->iz;       //si no hay hijo der pero si iz devuelvo subarbol iz 
        } 
        else{ 
            a = menor(arbol->der); 
            cont = a->contenido; 
            b = rastreaAnterior(a); //busco el que apuntaba a aux para ponerlo en null 
            b->iz = NULL; //se que es el izquierdo pq cuando busco el menor siempre va a estar a la iz 
            free(a
);    //Libero a, osea, remuevo el nodo a remover              return b;   //Devuelvo b que es el nodo que apuntaba  
        }
    } 
    arbol->contenido = cont; 
}
 
vamos por buen camino?
como podriamos hacer la parte del else{} de la funcion anterior.
ah!, me olvidaba, en el removerBlanaceado, llamo a una funcion auxiliar que me devuelve el que apunta a un nodo en particular, le paso el nodo minimo y cuando obtengo el nodo que lo apuntaba hago q apunte a NULL, parece razonable, el problema es que me parece medio enredado, y se que debe alguna otra forma para hacerlo mas eficiente.
si alguien nos puede ayudar se lo agradecemos 

saludos!