Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Funcion borrar en ABB

Estas en el tema de Funcion borrar en ABB en el foro de C/C++ en Foros del Web. Hola, estoy teniendo problemas con la funcion borrar en la implementacion de un arbol binario de busqueda. @import url("http://static.forosdelweb.com/clientscript/vbulletin_css/geshi.css"); Código C: Ver original typedef int ...
  #1 (permalink)  
Antiguo 18/05/2013, 03:51
 
Fecha de Ingreso: septiembre-2011
Mensajes: 42
Antigüedad: 12 años, 7 meses
Puntos: 3
Funcion borrar en ABB

Hola, estoy teniendo problemas con la funcion borrar en la implementacion de un arbol binario de busqueda.

Código C:
Ver original
  1. typedef int tipoElem;
  2.  
  3. typedef struct nodo{
  4.         tipoElem info;
  5.         struct nodo *izq;
  6.         struct nodo *der;
  7. }tNodo;
  8.  
  9. typedef struct{
  10.         tNodo *raiz;
  11.         int nElems;
  12. }tABB;
  13.  
  14. // elimina un elemento “item” de un ABB
  15. tNodo suce_pred(tNodo *nodo){
  16.       if (nodo->der == NULL) return *nodo;
  17.       else suce_pred(nodo->der);
  18. }
  19. void hijo_unico(tNodo *nodo){
  20.      if (nodo->izq == NULL){
  21.                    nodo->info = nodo->der->info;
  22.                    nodo->izq = nodo->der->izq;
  23.                    nodo->der = nodo->der->der;
  24.                    free((void *) nodo->der);
  25.      }
  26.      else{
  27.           nodo->info = nodo->izq->info;
  28.           nodo->izq = nodo->izq->izq;
  29.           nodo->der = nodo->izq->der;
  30.           free((void *) nodo->izq);
  31.      }
  32. }
  33. void dos_hijos(tNodo *nodo){
  34.      tNodo *aux;
  35.      *aux = suce_pred(nodo->izq);
  36.      nodo->info = aux->info;
  37.      hijo_unico(aux);
  38. }
  39. void removeHelp(tNodo *nodo, tipoElem item){
  40.      if (item == nodo->info){
  41.               if (nodo->izq == NULL && nodo->der == NULL){
  42.                             nodo = NULL;
  43.               }
  44.               else if (nodo->izq != NULL && nodo->der != NULL) dos_hijos(nodo);
  45.               else hijo_unico(nodo);
  46.      }
  47.      else if (item < nodo->info) removeHelp(nodo->izq, item);
  48.      else removeHelp(nodo->der, item);
  49. }
  50. void remove_n (tABB *T, tipoElem item){
  51.      removeHelp(T->raiz, item);
  52. }
  53.  
  54. int main(){
  55.     tABB A;
  56.     int c[7]={10,15,12,17,5,7,2};
  57.     int b;
  58.     initTree(&A);
  59.     for (b=0; b<7; b++){
  60.         inserta(&A, c[b]);
  61.     }
  62.     inOrden(&A);
  63.     printf("\n%d\n", size(&A));
  64.     remove_n(&A, 7);
  65.     printf("%d\n", find(&A, 7));
  66.     inOrden(&A);
  67.     getch();
  68. }

El problema es que no la borra despues de aplicar "remove_n". Pero si dentro de la funcion helpRemove, intento imprimir el valor del nodo que asigne a NULL, se me cae el programa (por razones obvias).
Por lo que supongo, que la funcion me esta eliminando el puntero y lo trata como variable local, por eso efectivamente lo asigne como NULL y se cae al imprimir su valor, pero no lo elimine del arbol "original".

¿En que parte esta el error?

Gracias de antemano
Saludos.
__________________
"Porque nada se...
quiero saberlo todo"
  #2 (permalink)  
Antiguo 19/05/2013, 15:40
 
Fecha de Ingreso: septiembre-2011
Mensajes: 42
Antigüedad: 12 años, 7 meses
Puntos: 3
Respuesta: Funcion borrar en ABB

Alguien ve donde esta el error?
__________________
"Porque nada se...
quiero saberlo todo"
  #3 (permalink)  
Antiguo 19/05/2013, 16:26
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 1 mes
Puntos: 1360
Respuesta: Funcion borrar en ABB

Hace varios años hice algunas implementaciones (de las cuales no estoy orgulloso) de diferentes estructuras de datos. https://github.com/razpeitia/data-structures

Una de las cosas que no me gusto fue que para imprimir bonito un árbol necesitaba usar una o dos queue. Y otra que el borrado de un nodo de un árbol binario no es trivial.

Básicamente para borrar tienes 3 casos:
1. El nodo es una hoja. Lo cual es sencillo por que buscas al padre del nodo y si tiene padre buscas si eres el nodo derecho o izquierdo y eso ahora apunta a null, liberas la memoria de tu nodo y listo.
2. El nodo tiene un solo hijo, en ese caso dejas a ese hijo como y eliminas tu nodo. Obviamente buscas el padre y actualizas las referencias.
3. El nodo tiene 2 hijos. Este es el peor de los casos peor es sencillo, tienes que buscar al mayor elemento que no sea mas grande que el. Si tienes el menor a la izquierda y el mayor a la derecha entonces busca el elemento mas a la derecha del subarbol izquierdo que no tenga un hijo a su lado derecho. Haz el cambio de datos entre ese nodo y el nodo que vas a borrar. Elimina el nodo que sucesor.

Wikipedia ofrece una mejor explicacion con dibujitos.
http://en.wikipedia.org/wiki/Binary_..._tree#Deletion

Aquí te dejo un ejemplo completamente funcional de un árbol binario. Y un queue.
https://gist.github.com/razpeitia/5609319

Etiquetas: funcion, int, programa, struct, variable
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:20.