Jelajahi Sumber

update bitree

joe 4 tahun lalu
induk
melakukan
84f9304d19
4 mengubah file dengan 56 tambahan dan 49 penghapusan
  1. 14 16
      include/ds/bitree.h
  2. 5 0
      include/ds/common.h
  3. 34 30
      src/bitree.c
  4. 3 3
      test/test_bitree.h

+ 14 - 16
include/ds/bitree.h

@@ -6,33 +6,31 @@
  */
 #include "common.h"
 
-typedef struct ds_bitree_node_t {
-  ds_data_t data;
-  struct ds_bitree_node_t* left;
-  struct ds_bitree_node_t* right;
-}ds_bitree_node_t;
+typedef struct _ds_binode {
+  DS_TREE_NODE_COMMON(struct _ds_binode);
+}ds_binode_t;
 
 typedef struct ds_bitree_t {
   int size;
-  ds_bitree_node_t* root;
+  ds_binode_t* root;
   func_destroyer destroyer;
-  func_comparer comparer;
 }ds_bitree_t;
 
-ds_bitree_t* ds_bitree_init(func_destroyer destroyer);
-void ds_bitree_destroy(ds_bitree_t* tree);
+ds_bitree_t* ds_bitree_new(func_destroyer destroyer);
+int ds_bitree_init(ds_bitree_t* tree, func_destroyer destroyer);
+void ds_bitree_destroy(ds_bitree_t* tree, int free_tree);
 
-int ds_bitree_ins_left(ds_bitree_t* tree, ds_bitree_node_t* node, ds_data_t data);
-int ds_bitree_ins_right(ds_bitree_t* tree, ds_bitree_node_t* node, ds_data_t data);
+int ds_bitree_ins_left(ds_bitree_t* tree, ds_binode_t* node, ds_data_t data);
+int ds_bitree_ins_right(ds_bitree_t* tree, ds_binode_t* node, ds_data_t data);
 
-int ds_bitree_rm_left(ds_bitree_t* tree, ds_bitree_node_t* node);
-int ds_bitree_rm_right(ds_bitree_t* tree, ds_bitree_node_t* node);
+int ds_bitree_rm_left(ds_bitree_t* tree, ds_binode_t* node);
+int ds_bitree_rm_right(ds_bitree_t* tree, ds_binode_t* node);
 
 ds_bitree_t* ds_bitree_merge(ds_bitree_t*left, ds_bitree_t*right, ds_data_t data);
 
-void ds_bitree_preorder(ds_bitree_node_t* node, func_each each);
-void ds_bitree_inorder(ds_bitree_node_t* node, func_each each);
-void ds_bitree_postorder(ds_bitree_node_t* node, func_each each);
+void ds_bitree_preorder(ds_binode_t* node, func_each each);
+void ds_bitree_inorder(ds_binode_t* node, func_each each);
+void ds_bitree_postorder(ds_binode_t* node, func_each each);
 
 #define ds_bitree_size(tree) ((tree)->size)
 #define ds_bitree_root(tree) ((tree)->root)

+ 5 - 0
include/ds/common.h

@@ -28,6 +28,11 @@ int ds_cb_default_comparer(ds_data_t, ds_data_t);
 
 #define IMPL_FOREACH \
   (void*)0
+  
+#define DS_TREE_NODE_COMMON(node_type) \
+    ds_data_t data; \
+    node_type* left; \
+    node_type* right
 
 #define UNUSED(x) (void*)(x)
 

+ 34 - 30
src/bitree.c

@@ -4,7 +4,7 @@
 extern func_malloc ds_malloc;
 extern func_free ds_free;
 
-ds_bitree_t* ds_bitree_init(func_destroyer destroyer)
+ds_bitree_t* ds_bitree_new(func_destroyer destroyer)
 {
   ds_bitree_t* tree = (ds_bitree_t*)ds_malloc(sizeof(ds_bitree_t));
   if (!tree) {
@@ -12,24 +12,32 @@ ds_bitree_t* ds_bitree_init(func_destroyer destroyer)
   }
   tree->size = 0;
   tree->root = NULL;
-  tree->destroyer = destroyer;
-  tree->comparer = NULL;
+  tree->destroyer = destroyer ? destroyer : ds_cb_default_destroyer;
   return tree;
 }
 
-void ds_bitree_destroy(ds_bitree_t* tree)
+int ds_bitree_init(ds_bitree_t* tree, func_destroyer destroyer)
+{
+    tree->size = 0;
+    tree->root = NULL;
+    tree->destroyer = destroyer ? destroyer : ds_cb_default_destroyer;
+    
+    return DS_ERR_OK;
+}
+
+void ds_bitree_destroy(ds_bitree_t* tree, int free_tree)
 {
   ds_bitree_rm_left(tree, NULL);
 
-  ds_free(tree);
-  tree = NULL;
+  if (free_tree)
+    ds_free(tree);
 }
 
-int ds_bitree_ins_left(ds_bitree_t* tree, ds_bitree_node_t* node, ds_data_t data)
+int ds_bitree_ins_left(ds_bitree_t* tree, ds_binode_t* node, ds_data_t data)
 {
-  ds_bitree_node_t * new_node, **pos;
+  ds_binode_t * new_node, **pos;
   if (!node) {
-    if (ds_bitree_size(tree) > 0) {
+    if (ds_bitree_size(tree) > 0) { // has root already
       return DS_ERR_PARAMS;
     }
     pos = &(tree->root);
@@ -39,7 +47,7 @@ int ds_bitree_ins_left(ds_bitree_t* tree, ds_bitree_node_t* node, ds_data_t data
     }
     pos = &(node->left);
   }
-  if((new_node = (ds_bitree_node_t*)ds_malloc(sizeof(ds_bitree_node_t))) == NULL) {
+  if ((new_node = (ds_binode_t*)ds_malloc(sizeof(ds_binode_t))) == NULL) {
     return DS_ERR_MEM;
   }
 
@@ -53,9 +61,9 @@ int ds_bitree_ins_left(ds_bitree_t* tree, ds_bitree_node_t* node, ds_data_t data
   return DS_ERR_OK;
 }
 
-int ds_bitree_ins_right(ds_bitree_t* tree, ds_bitree_node_t* node, ds_data_t data)
+int ds_bitree_ins_right(ds_bitree_t* tree, ds_binode_t* node, ds_data_t data)
 {
-  ds_bitree_node_t * new_node, **pos;
+  ds_binode_t * new_node, **pos;
   if (!node) {
     if (ds_bitree_size(tree) > 0) {
       return DS_ERR_PARAMS;
@@ -67,7 +75,7 @@ int ds_bitree_ins_right(ds_bitree_t* tree, ds_bitree_node_t* node, ds_data_t dat
     }
     pos = &(node->right);
   }
-  if((new_node = (ds_bitree_node_t*)ds_malloc(sizeof(ds_bitree_node_t))) == NULL) {
+  if((new_node = (ds_binode_t*)ds_malloc(sizeof(ds_binode_t))) == NULL) {
     return DS_ERR_MEM;
   }
 
@@ -81,9 +89,9 @@ int ds_bitree_ins_right(ds_bitree_t* tree, ds_bitree_node_t* node, ds_data_t dat
   return DS_ERR_OK;
 }
 
-int ds_bitree_rm_left(ds_bitree_t* tree, ds_bitree_node_t* node)
+int ds_bitree_rm_left(ds_bitree_t* tree, ds_binode_t* node)
 {
-  ds_bitree_node_t ** pos;
+  ds_binode_t ** pos;
   if (ds_bitree_size(tree) <= 0) {
     return DS_ERR_EMPTY;
   }
@@ -97,10 +105,8 @@ int ds_bitree_rm_left(ds_bitree_t* tree, ds_bitree_node_t* node)
     ds_bitree_rm_left(tree, *pos);
     ds_bitree_rm_right(tree, *pos);
 
-    if(tree->destroyer) {
-      tree->destroyer((*pos)->data);
-    }
-
+    tree->destroyer((*pos)->data);
+    
     ds_free(*pos);
     *pos = NULL;
 
@@ -109,9 +115,9 @@ int ds_bitree_rm_left(ds_bitree_t* tree, ds_bitree_node_t* node)
   return DS_ERR_OK;
 }
 
-int ds_bitree_rm_right(ds_bitree_t* tree, ds_bitree_node_t* node)
+int ds_bitree_rm_right(ds_bitree_t* tree, ds_binode_t* node)
 {
-  ds_bitree_node_t**pos;
+  ds_binode_t **pos;
   if (ds_bitree_size(tree) <= 0){
     return DS_ERR_EMPTY;
   }
@@ -125,13 +131,11 @@ int ds_bitree_rm_right(ds_bitree_t* tree, ds_bitree_node_t* node)
     ds_bitree_rm_left(tree, *pos);
     ds_bitree_rm_right(tree, *pos);
 
-    if(tree->destroyer){
-      tree->destroyer((*pos)->data);
-    }
+    tree->destroyer((*pos)->data);
 
     ds_free(*pos);
     *pos = NULL;
-
+    
     tree->size--;
   }
   return DS_ERR_OK;
@@ -139,13 +143,13 @@ int ds_bitree_rm_right(ds_bitree_t* tree, ds_bitree_node_t* node)
 
 ds_bitree_t* ds_bitree_merge(ds_bitree_t*left, ds_bitree_t*right, ds_data_t data)
 {
-  ds_bitree_t *new_tree = ds_bitree_init(left->destroyer);
+  ds_bitree_t *new_tree = ds_bitree_new(left->destroyer);
   if(!new_tree) {
     return NULL;
   }
   int err;
   if((err = ds_bitree_ins_left(new_tree, NULL, data)) != DS_ERR_OK) {
-    ds_bitree_destroy(new_tree);
+    ds_bitree_destroy(new_tree, 1);
     return NULL;
   }
 
@@ -160,7 +164,7 @@ ds_bitree_t* ds_bitree_merge(ds_bitree_t*left, ds_bitree_t*right, ds_data_t data
   return new_tree;
 }
 
-void ds_bitree_preorder(ds_bitree_node_t* node, func_each each)
+void ds_bitree_preorder(ds_binode_t* node, func_each each)
 {
   if(node){
     if(each){
@@ -171,7 +175,7 @@ void ds_bitree_preorder(ds_bitree_node_t* node, func_each each)
   }
 }
 
-void ds_bitree_inorder(ds_bitree_node_t* node, func_each each)
+void ds_bitree_inorder(ds_binode_t* node, func_each each)
 {
   if(node) {
     ds_bitree_inorder(node->left, each);
@@ -182,7 +186,7 @@ void ds_bitree_inorder(ds_bitree_node_t* node, func_each each)
   }
 }
 
-void ds_bitree_postorder(ds_bitree_node_t* node, func_each each)
+void ds_bitree_postorder(ds_binode_t* node, func_each each)
 {
   if(node) {
     ds_bitree_postorder(node->left, each);

+ 3 - 3
test/test_bitree.h

@@ -10,13 +10,13 @@
 #include <ds.h>
 
 int tree_printer(void* node){
-  ds_bitree_node_t* n = (ds_bitree_node_t*)node;
+  ds_binode_t* n = (ds_binode_t*)node;
   printf("%d\n", (int)ds_bitree_data(n));
   return 1;
 }
 
 void test_bitree_generally(void **state) {
-  ds_bitree_t* tree = ds_bitree_init(NULL);
+  ds_bitree_t* tree = ds_bitree_new(NULL);
   ds_bitree_ins_left(tree, NULL, (ds_data_t)1);
 
   ds_bitree_ins_left(tree, ds_bitree_root(tree), (ds_data_t)2);
@@ -28,7 +28,7 @@ void test_bitree_generally(void **state) {
   ds_bitree_inorder(ds_bitree_root(tree), tree_printer);
   ds_bitree_postorder(ds_bitree_root(tree), tree_printer);
 
-  ds_bitree_destroy(tree);
+  ds_bitree_destroy(tree, 1);
 
   UNUSED(state);
 }