Advertisement
Guest User

abb final

a guest
Jun 24th, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.52 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "abb.h"
  5. #include "pila.h"
  6.  
  7. const int TAMANIO_INICIAL= 0;
  8. const int DAR_PADRE= 1;
  9. const int NO_DAR_PADRE= -1;
  10. const int IZQ= -1;
  11. const int DER= 1;
  12.  
  13. /* Definición del struct nodo.
  14.  */
  15.  typedef struct nodo {
  16.      void* dato;
  17.      char* clave;
  18. }nodo_t;
  19.  
  20. /* Definición del struct abb_nodo.
  21.  */
  22. typedef struct abb_nodo {
  23.     nodo_t* nodo;
  24.     struct abb_nodo* izq;
  25.     struct abb_nodo* der;
  26. }abb_nodo_t;
  27.  
  28. /* Definición del struct abb.
  29.  */
  30. struct abb {
  31.     abb_nodo_t* raiz;
  32.     size_t cantidad_nodos;
  33.     abb_comparar_clave_t cmp;
  34.     abb_destruir_dato_t destruir_dato;
  35. };
  36.  
  37. /* Definición del struct abb_iter.
  38.  */
  39. struct abb_iter{
  40.     const abb_t* arbol;
  41.     pila_t *pila;
  42. };
  43.  
  44. /* ******************************************************************
  45.  *                    FUNCIONES AUXILIARES
  46.  * *****************************************************************/
  47. char* duplicar_clave(const char* clave) {
  48.     size_t largo= strlen(clave)+1; //sumo 1 para el \0
  49.     char* dup_clave = malloc(sizeof(char)*largo);
  50.     if(dup_clave == NULL) {
  51.         return NULL;
  52.     }
  53.     strcpy(dup_clave, clave);
  54.     return dup_clave;
  55. }
  56.  
  57. nodo_t* nodo_crear(const char* clave, void* dato) {
  58.    
  59.     nodo_t* nodo = malloc(sizeof(nodo_t));
  60.     if (nodo == NULL) {
  61.         return NULL;
  62.     }
  63.     nodo->clave = duplicar_clave(clave);
  64.     if(nodo->clave == NULL) {
  65.         return NULL;
  66.     }
  67.     nodo->dato = dato;
  68.     return nodo;
  69. }
  70.  
  71. abb_nodo_t* nodo_abb_crear(const char* clave, void* dato) {
  72.    
  73.     abb_nodo_t* nuevo_nodo= malloc(sizeof(abb_nodo_t));
  74.    
  75.     if(nuevo_nodo == NULL) {
  76.         return NULL;
  77.     }
  78.    
  79.     nuevo_nodo->nodo= nodo_crear(clave, dato);
  80.    
  81.     if(nuevo_nodo->nodo == NULL) {
  82.         return NULL;
  83.     }
  84.    
  85.     nuevo_nodo->der= NULL;
  86.     nuevo_nodo->izq= NULL;
  87.     return nuevo_nodo; 
  88. }
  89.  
  90. void* borrar_nodo(abb_nodo_t* nodo_borrar) {
  91.     void* dato= nodo_borrar->nodo->dato;
  92.     free(nodo_borrar->nodo->clave);
  93.     free(nodo_borrar->nodo);
  94.     free(nodo_borrar);
  95.     return dato;
  96. }
  97.  
  98. void swappeo_nodos_abb(abb_nodo_t* padre, abb_nodo_t* hijo) {
  99.     nodo_t* nodo_aux= padre->nodo;
  100.     padre->nodo= hijo->nodo;
  101.     hijo->nodo= nodo_aux;
  102. }
  103.  
  104. int hijo_izq_o_der(abb_nodo_t* padre) {
  105.     if(padre->der) {
  106.         return DER;
  107.     }
  108.     return IZQ;
  109. }
  110.  
  111. bool guardar_nodo_en_el_arbol(abb_t* arbol, abb_nodo_t* padre, abb_nodo_t* hijo) {
  112.    
  113.     if(arbol->cmp(padre->nodo->clave, hijo->nodo->clave) < 0) {
  114.         if(padre->der == NULL) {
  115.             padre->der= hijo;
  116.             arbol->cantidad_nodos += 1;
  117.             return true;
  118.         }else {
  119.             return guardar_nodo_en_el_arbol(arbol, padre->der, hijo);
  120.         }
  121.     }else if(arbol->cmp(padre->nodo->clave, hijo->nodo->clave) > 0) {
  122.         if(padre->izq == NULL) {
  123.             padre->izq= hijo;
  124.             arbol->cantidad_nodos += 1;
  125.             return true;
  126.         }else {
  127.             return guardar_nodo_en_el_arbol(arbol, padre->izq, hijo);
  128.         }
  129.     }
  130.     //si son iguales
  131.     swappeo_nodos_abb(padre, hijo);
  132.     void* dato= borrar_nodo(hijo);
  133.     if(arbol->destruir_dato != NULL) {
  134.         arbol->destruir_dato(dato);
  135.     }
  136.     return true;
  137. }
  138.  
  139. abb_nodo_t* abb_nodo_buscar(const abb_t* arbol, abb_nodo_t* nodo_actual, const char* clave, int devuelvo_el_padre) {
  140.    
  141.     if(nodo_actual == NULL) {
  142.         return NULL;
  143.     }
  144.    
  145.     int cmp= arbol->cmp(nodo_actual->nodo->clave, clave);
  146.     bool esta= false;
  147.    
  148.     if(devuelvo_el_padre == DAR_PADRE) {
  149.         if(cmp == 0) {
  150.             return NULL;
  151.         }else if(arbol->cmp(nodo_actual->izq->nodo->clave, clave) == 0) {
  152.             return nodo_actual;
  153.         }else if(arbol->cmp(nodo_actual->der->nodo->clave, clave) == 0) {
  154.             return nodo_actual;
  155.         }
  156.     }
  157.    
  158.     if( cmp < 0) {
  159.         return abb_nodo_buscar(arbol, nodo_actual->der, clave, devuelvo_el_padre);
  160.     }else if(cmp > 0) {
  161.         return abb_nodo_buscar(arbol, nodo_actual->izq, clave, devuelvo_el_padre);
  162.     }else if(cmp == 0) {
  163.         esta= true;
  164.     }
  165.    
  166.     if(!esta) {
  167.         return NULL;
  168.     }
  169.    
  170.     return nodo_actual;
  171. }
  172.  
  173. abb_nodo_t* buscar_hijo(abb_nodo_t* padre) {
  174.     int pos_hijo= hijo_izq_o_der(padre);
  175.    
  176.     if(pos_hijo == DER) {
  177.         return padre->der;
  178.     }
  179.     return padre->izq;
  180. }
  181.  
  182. void destruir_abb(abb_t* arbol, abb_nodo_t* nodo_actual) {
  183.    
  184.     if(nodo_actual == NULL) {
  185.         return;
  186.     }
  187.     destruir_abb(arbol, nodo_actual->izq);
  188.     destruir_abb(arbol, nodo_actual->der);
  189.     void* dato= borrar_nodo(nodo_actual);
  190.    
  191.     if(arbol->destruir_dato != NULL) {
  192.         arbol->destruir_dato(dato);
  193.     }
  194. }
  195.  
  196. // Me devuelve el nodo que esta mas a la izquierda del nodo que voy a eliminar
  197. abb_nodo_t* buscar_minimo(abb_nodo_t* nodo_actual) {
  198.    
  199.     if(nodo_actual == NULL) {
  200.         return NULL;
  201.     }
  202.    
  203.     if(nodo_actual->izq != NULL) {
  204.         return buscar_minimo(nodo_actual->izq);
  205.     }
  206.     return nodo_actual;
  207. }
  208.  
  209. bool nodo_hoja(abb_nodo_t* nodo_actual) {
  210.     if(nodo_actual->izq == NULL && nodo_actual->der == NULL) {
  211.         return true;
  212.     }
  213.     return false;
  214. }
  215.  
  216. bool nodo_un_hijo(abb_nodo_t* nodo_actual) {
  217.     if(nodo_actual->izq != NULL && nodo_actual->der == NULL) {
  218.         return true;
  219.     }else if(nodo_actual->izq == NULL && nodo_actual->der != NULL) {
  220.         return true;
  221.     }
  222.     return false;
  223. }
  224.  
  225. bool nodo_dos_hijos(abb_nodo_t* nodo_actual) {
  226.     if(nodo_actual->izq != NULL && nodo_actual->der != NULL) {
  227.         return true;
  228.     }
  229.     return false;
  230. }
  231.  
  232. void* borro_hoja(abb_t* arbol, abb_nodo_t* padre, abb_nodo_t* hijo) {
  233.    
  234.     if(hijo == arbol->raiz) {
  235.         arbol->raiz= NULL;
  236.         arbol->cantidad_nodos -=1;
  237.         return borrar_nodo(hijo);
  238.     }
  239.     int cmp= arbol->cmp(padre->nodo->clave, hijo->nodo->clave);
  240.  
  241.     if(cmp < 0) {
  242.         padre->der= NULL;
  243.     }else {
  244.         padre->izq= NULL;
  245.     }
  246.     arbol->cantidad_nodos -=1;
  247.     return borrar_nodo(hijo);
  248. }
  249.  
  250. void* borro_nodo_con_un_hijo(abb_t* arbol, abb_nodo_t* abuelo, abb_nodo_t* padre) {
  251.    
  252.     abb_nodo_t* nieto= buscar_hijo(padre);
  253.    
  254.     if(padre == arbol->raiz){
  255.         arbol->raiz= nieto;
  256.         arbol->cantidad_nodos -=1;
  257.         return borrar_nodo(padre);
  258.     }
  259.    
  260.     int pos_hijo= hijo_izq_o_der(abuelo);
  261.    
  262.     if(pos_hijo == DER) {
  263.         abuelo->der= nieto;
  264.     }else{
  265.         abuelo->izq= nieto;
  266.     }
  267.     arbol->cantidad_nodos -=1;
  268.     return borrar_nodo(padre);
  269. }
  270.  
  271. /* ******************************************************************
  272.  *                    PRIMITIVAS DEL ABB
  273.  * *****************************************************************/
  274. abb_t* abb_crear(abb_comparar_clave_t cmp, abb_destruir_dato_t destruir_dato) {
  275.    
  276.     abb_t* abb= malloc(sizeof(abb_t));
  277.    
  278.     if(abb == NULL) {
  279.         return NULL;
  280.     }
  281.    
  282.     abb->raiz= NULL;
  283.     abb->cmp= cmp;
  284.     abb->destruir_dato= destruir_dato;
  285.     abb->cantidad_nodos= TAMANIO_INICIAL;
  286.     return abb;
  287. }
  288.  
  289. bool abb_guardar(abb_t* arbol, const char* clave, void* dato) {
  290.    
  291.     abb_nodo_t* nodo_nuevo= nodo_abb_crear(clave, dato);
  292.    
  293.     if(nodo_nuevo == NULL) {
  294.         return false;
  295.     }
  296.    
  297.     if(arbol->raiz == NULL) {
  298.         arbol->raiz= nodo_nuevo;
  299.         arbol->cantidad_nodos += 1;
  300.         return true;
  301.     }else {
  302.         if(guardar_nodo_en_el_arbol(arbol, arbol->raiz, nodo_nuevo)) {
  303.             return true;
  304.         }
  305.     }
  306.     return false;
  307. }
  308.  
  309. void* abb_borrar(abb_t* arbol, const char* clave) {
  310.    
  311.     if(abb_cantidad(arbol) == 0 || !abb_pertenece(arbol, clave)){
  312.         return NULL;
  313.     }
  314.    
  315.     abb_nodo_t* padre= abb_nodo_buscar(arbol, arbol->raiz, clave, DAR_PADRE);
  316.     abb_nodo_t* nodo_actual= abb_nodo_buscar(arbol, arbol->raiz, clave, NO_DAR_PADRE);
  317.    
  318.     // si nodo actual es una hoja
  319.     if(nodo_hoja(nodo_actual)) {
  320.         return borro_hoja(arbol, padre, nodo_actual);
  321.     }
  322.     if(nodo_un_hijo(nodo_actual)) {
  323.         return borro_nodo_con_un_hijo(arbol, padre, nodo_actual);
  324.     }
  325.    
  326.     // si nodo actual es un nodo con dos hijos
  327.     if(nodo_dos_hijos(nodo_actual)) {
  328.         abb_nodo_t* nodo_minimo= buscar_minimo(nodo_actual->der);
  329.         abb_nodo_t* padre_minimo= abb_nodo_buscar(arbol, arbol->raiz, nodo_minimo->nodo->clave, DAR_PADRE);
  330.         swappeo_nodos_abb(nodo_actual, nodo_minimo);
  331.        
  332.         if(nodo_hoja(nodo_minimo)) {
  333.             return borro_hoja(arbol, padre_minimo, nodo_minimo);
  334.         }else if(nodo_un_hijo(nodo_minimo)){
  335.             padre_minimo->izq= nodo_minimo->der;
  336.         }
  337.         arbol->cantidad_nodos -=1;
  338.         return borrar_nodo(nodo_minimo);
  339.     }
  340.    
  341.     return NULL;
  342. }
  343.  
  344. void *abb_obtener(const abb_t *arbol, const char *clave) {
  345.  
  346.     abb_nodo_t* nodo_a_buscar = abb_nodo_buscar(arbol, arbol->raiz, clave, NO_DAR_PADRE);
  347.  
  348.     if(!nodo_a_buscar) {
  349.         return NULL;
  350.     }
  351.     return nodo_a_buscar->nodo->dato;
  352. }
  353.  
  354. bool abb_pertenece(const abb_t* arbol, const char* clave) {
  355.  
  356.     abb_nodo_t* nodo_a_buscar = abb_nodo_buscar(arbol, arbol->raiz, clave, NO_DAR_PADRE);
  357.  
  358.     return (nodo_a_buscar != NULL);
  359. }
  360.  
  361. size_t abb_cantidad(abb_t *arbol) {
  362.     return(arbol->cantidad_nodos);
  363. }
  364.  
  365. void abb_destruir(abb_t* arbol) {
  366.     destruir_abb(arbol, arbol->raiz);
  367.     free(arbol);
  368. }    
  369.  
  370.  /* *****************************************************************
  371.  *               PRIMITIVAS DEL ITERADOR EXTERNO
  372.  * *****************************************************************/
  373.  
  374. abb_iter_t *abb_iter_in_crear(const abb_t *arbol) {
  375.  
  376.     abb_iter_t* nuevo_iter = malloc(sizeof(abb_iter_t));
  377.     if(!nuevo_iter) {
  378.         return NULL;
  379.     }
  380.     nuevo_iter->arbol = arbol;
  381.     nuevo_iter->pila = pila_crear();
  382.    
  383.     if(!nuevo_iter->pila) {
  384.         free(nuevo_iter);
  385.         return NULL;
  386.     }
  387.    
  388.     abb_nodo_t* nodo_actual = arbol->raiz;
  389.  
  390.     while(nodo_actual != NULL) {
  391.         pila_apilar(nuevo_iter->pila, nodo_actual);
  392.         nodo_actual = nodo_actual->izq;
  393.     }
  394.    
  395.     return nuevo_iter;
  396. }
  397.  
  398. bool abb_iter_in_avanzar(abb_iter_t *iter) {
  399.     if(abb_iter_in_al_final(iter)) {
  400.         return false;
  401.     }
  402.    
  403.     abb_nodo_t* nodo_actual= pila_desapilar(iter->pila);
  404.    
  405.     if(nodo_actual->der != NULL) {
  406.        
  407.         pila_apilar(iter->pila, nodo_actual->der);
  408.         nodo_actual= nodo_actual->der;
  409.        
  410.         while(nodo_actual->izq != NULL) {
  411.             pila_apilar(iter->pila, nodo_actual->izq);
  412.             nodo_actual= nodo_actual->izq;
  413.         }
  414.     }
  415.     return true;
  416. }
  417.  
  418. bool abb_iter_in_al_final(const abb_iter_t *iter) {
  419.     return pila_esta_vacia(iter->pila);
  420. }
  421.  
  422. const char* abb_iter_in_ver_actual(const abb_iter_t *iter) {
  423.     if(abb_iter_in_al_final(iter))
  424.         return NULL;
  425.  
  426.     abb_nodo_t* nodo_actual = pila_ver_tope(iter->pila);
  427.     return (nodo_actual->nodo->clave);
  428. }
  429.  
  430. void abb_iter_in_destruir(abb_iter_t* iter){
  431.     pila_destruir(iter->pila);
  432.     free(iter);
  433. }
  434.  
  435. /* ******************************************************************
  436.  *                    PRIMITIVAS DEL ITERADOR INTERNO
  437.  * *****************************************************************/
  438.  
  439. void abb_iterar(abb_nodo_t* nodo_actual, bool visitar(const char *, void *, void *), void *extra){
  440.    
  441.     if(nodo_actual == NULL){
  442.         return;
  443.     }
  444.    
  445.     abb_iterar(nodo_actual->izq, visitar, extra);
  446.     visitar(nodo_actual->nodo->clave, nodo_actual->nodo->dato, extra);
  447.     abb_iterar(nodo_actual->der, visitar, extra);
  448. }
  449.  
  450. void abb_in_order(abb_t* arbol, bool visitar(const char *, void *, void *), void *extra){
  451.     abb_iterar(arbol->raiz, visitar, extra);
  452. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement