]> git.mdlowis.com Git - projs/libcds.git/commitdiff
First draft of binary tree implementation
authorMike D. Lowis <mike@mdlowis.com>
Thu, 18 Apr 2013 01:09:16 +0000 (21:09 -0400)
committerMike D. Lowis <mike@mdlowis.com>
Thu, 18 Apr 2013 01:09:16 +0000 (21:09 -0400)
source/buffer/buf.h
source/list/list.h
source/tree/tree.c [new file with mode: 0644]
source/tree/tree.h
source/vector/vec.h
tests/test_tree.cpp [new file with mode: 0644]

index 773d34b9f1bfe77da788aac58071bb922868fa24..483c43498577113ef3e2af352f7d00cf7ceed991 100644 (file)
@@ -11,6 +11,7 @@
 extern "C" {
 #endif
 
+#include <string.h>
 #include <stdbool.h>
 
 /** A structure defining a circular buffer */
index 5a146c2b9a9dce267d713533c0c35b3e6a0bd058..80bde49527244eb580751d262176e41eab6365d9 100644 (file)
@@ -5,6 +5,7 @@
 extern "C" {
 #endif
 
+#include <string.h>
 #include <stdbool.h>
 
 /** A linked list node. */
@@ -30,7 +31,7 @@ typedef struct list_t
  *
  * @return A pointer to the newly created list.
  **/
-extern list_t* list_new(void);
+list_t* list_new(void);
 
 /**
  * @brief Creates a new node with given contents.
diff --git a/source/tree/tree.c b/source/tree/tree.c
new file mode 100644 (file)
index 0000000..051ec9b
--- /dev/null
@@ -0,0 +1,169 @@
+/**
+  @file tree.c
+  @brief See header for details
+  $Revision$
+  $HeadURL$
+  */
+#include <stdlib.h>
+#include "tree.h"
+
+tree_t* tree_new(tree_cmp_fn_t cmp_fn)
+{
+    tree_t* tree = (tree_t*)malloc(sizeof(tree_t));
+    tree->cmp_fn = (NULL == cmp_fn) ? tree_cmp_ptrs : cmp_fn;
+    tree->size = 0;
+    tree->root = NULL;
+    return tree;
+}
+
+tree_node_t* tree_new_node(void* value)
+{
+    tree_node_t* node = (tree_node_t*)malloc(sizeof(tree_node_t));
+    node->value = value;
+    node->left = NULL;
+    node->right = NULL;
+    return node;
+}
+
+int tree_cmp_ptrs(void* tval,void* fval)
+{
+    int ret = 0;
+    if (tval < fval)
+        ret = -1;
+    else if (tval > fval)
+        ret = 1;
+    return ret;
+}
+
+void tree_free(tree_t* tree, bool free_values)
+{
+    tree_free_node(tree->root, free_values);
+    free(tree);
+}
+
+void tree_free_node(tree_node_t* node, bool free_value)
+{
+    if (node->left != NULL)
+        tree_free_node(node->left, free_value);
+    if (node->right != NULL)
+        tree_free_node(node->right, free_value);
+    if (free_value)
+        free(node->value);
+    free(node);
+}
+
+bool tree_empty(tree_t* tree)
+{
+    return (tree_size(tree) == 0);
+}
+
+size_t tree_size(tree_t* tree)
+{
+    return tree->size;
+}
+
+size_t tree_max_size(void)
+{
+    return (size_t)(-1);
+}
+
+void tree_insert(tree_t* tree, void* value)
+{
+    bool finished = false;
+    tree_node_t* node = tree->root;
+    while(!finished)
+    {
+        switch (tree->cmp_fn(node->value, value))
+        {
+            // If the value is already in the tree
+            case 0:
+                // Nothing to do because it's already there.
+                finished = true;
+                break;
+
+            case -1:
+                if (NULL == node->right)
+                {
+                    node->right = tree_new_node( value );
+                    tree->size++;
+                    finished = true;
+                }
+                else
+                {
+                    node = node->right;
+                }
+                break;
+
+            case 1:
+                if (NULL == node->left)
+                {
+                    node->left = tree_new_node( value );
+                    tree->size++;
+                    finished = true;
+                }
+                else
+                {
+                    node = node->left;
+                }
+                break;
+        }
+    }
+}
+
+void* tree_at(tree_t* tree, void* value)
+{
+    void* ret_val = NULL;
+    tree_node_t* node = tree->root;
+    while(node != NULL)
+    {
+        switch (tree->cmp_fn(node->value, value))
+        {
+            case 0:
+                ret_val = node->value;
+                node = NULL;
+                break;
+
+            case -1:
+                node = node->right;
+                break;
+
+            case 1:
+                node = node->left;
+                break;
+        }
+    }
+    return ret_val;
+}
+
+void tree_erase(tree_t* tree, void* value)
+{
+    //tree_node_t* prev_node = NULL;
+    //tree_node_t* curr_node = tree->root;
+    //while(node != NULL)
+    //{
+    //    switch (tree->cmp_fn(node->value, value))
+    //    {
+    //        case 0:
+    //            ret_val = node->value;
+    //            node = NULL;
+    //            break;
+
+    //        case -1:
+    //            node = node->right;
+    //            break;
+
+    //        case 1:
+    //            node = node->left;
+    //            break;
+    //    }
+    //}
+}
+
+void tree_clear(tree_t* tree, bool free_values)
+{
+    tree->size = 0;
+    tree_free_node( tree->root, free_values );
+    tree->root = NULL;
+}
+
+
index 401a34535bf2a4d733f8fe904a7e930649a59605..1fe68363ad7ad3d9e10067fd051a3627757824c3 100644 (file)
 /**
     @file tree.h
-    @brief An implementation of a Red-Black binary tree.
+    @brief An implementation of a binary tree.
     $Revision$
     $HeadURL$
 */
 #ifndef TREE_H
 #define TREE_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
+#include <string.h>
+#include <stdbool.h>
+
+/** A node in a tree */
+typedef struct {
+    void* value; /*< The value of the node in the tree */
+    void* left;  /*< Pointer to the left child of the node */
+    void* right; /*< Pointer to the right child of the node */
+} tree_node_t;
+
+/** A comparison function used to compare node values when looking up or
+ * inserting values
+ *
+ * @param tval The "tree" value. The value stored in the tree.
+ * @param fval The "free" value. The value to be inserted, erased, or looked up.
+ *
+ * @return  0 if the values are equal.
+ *         -1 if "tree" value (tval) is less than "free" value (fval).
+ *          1 if "tree" value (tval) is greater than "free" value (fval).
+ **/
+typedef int (*tree_cmp_fn_t)(void* tval,void* fval);
+
+/** A binary tree */
+typedef struct {
+    tree_cmp_fn_t cmp_fn; /*< Comparison function used to compare values stored in the tree */
+    size_t size;          /*< The number of elements currently stored in the tree */
+    tree_node_t* root;    /*< Pointer to the root of the tree */
+} tree_t;
+
+/**
+ * @brief Create a new empty binary tree.
+ *
+ * @param cmp_fn The function to be used for comparing values.
+ *
+ * @return Pointer to the newly created tree.
+ */
+tree_t* tree_new(tree_cmp_fn_t cmp_fn);
+
+/**
+ * @brief Create a new tree node with the provided value.
+ *
+ * @param value The value to be stored in the node.
+ *
+ * @return Pointer to the newly created node.
+ */
+tree_node_t* tree_new_node(void* value);
+
+
+/**
+ * @brief Compare the raw pointer values provided.
+ *
+ * This function is the comparison function used if the user does not provide a
+ * function when the tree is initialized.
+ *
+ * @param tval The "tree" value. The value stored in the tree.
+ * @param fval The "free" value. The value to be inserted, erased, or looked up.
+ *
+ * @return  0 if the values are equal.
+ *         -1 if "tree" value (tval) is less than "free" value (fval).
+ *          1 if "tree" value (tval) is greater than "free" value (fval).
+ */
+int tree_cmp_ptrs(void* tval,void* fval);
+
+/**
+ * @brief Free the tree and all it's nodes.
+ *
+ * @param tree The tree to be freed.
+ * @param free_values Whether the value of each node should also be freed.
+ */
+void tree_free(tree_t* tree, bool free_values);
+
+/**
+ * @brief Frees the tree node.
+ *
+ * @param node The node to be freed.
+ * @param free_value Whether the value of the node should also be freed.
+ */
+void tree_free_node(tree_node_t* node, bool free_value);
+
+/**
+ * @brief Return whether the tree is empty or not.
+ *
+ * @param tree The tree in question.
+ *
+ * @return Whether the tree is empty or not.
+ */
+bool tree_empty(tree_t* tree);
+
+/**
+ * @brief Return the number of elements currently in the tree.
+ *
+ * @param tree The tree in question.
+ *
+ * @return The number of elements currently in the tree.
+ */
+size_t tree_size(tree_t* tree);
+
+/**
+ * @brief Return the maximum number of elements that can be stored in a tree.
+ *
+ * @return The maximum number of elements that can be stored in a tree.
+ */
+size_t tree_max_size(void);
+
+/**
+ * @brief Insert the given element in the given tree.
+ *
+ * @param tree The tree in which the element will be inserted.
+ * @param value The value to insert.
+ */
+void tree_insert(tree_t* tree, void* value);
+
+/**
+ * @brief Lookup the provided value in the provided tree.
+ *
+ * @param tree The tree in question.
+ * @param value Pointer to the value to find.
+ *
+ * @return Pointer to the matching value or NULL if none found.
+ */
+void* tree_at(tree_t* tree, void* value);
+
+/**
+ * @brief Erase from the tree the first element matching the provided value.
+ *
+ * @param tree The tree from which the value will be removed.
+ * @param value Pointer to the value to erase.
+ */
+void tree_erase(tree_t* tree, void* value);
+
+/**
+ * @brief Erase all values in the tree.
+ *
+ * @param tree The tree to clear.
+ * @param free_values Whether the values should be freed or not.
+ */
+void tree_clear(tree_t* tree, bool free_values);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* TREE_H */
index aa9d2d7478f3cb48e395f7ce7919da2d59c7ac09..1ef331edf8dfe7f78e950d9154b1cb32b40e49f4 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef VEC_H
 #define VEC_H
 
+#include <string.h>
 #include <stdarg.h>
 #include <stdbool.h>
 #include <stddef.h>
diff --git a/tests/test_tree.cpp b/tests/test_tree.cpp
new file mode 100644 (file)
index 0000000..8e12564
--- /dev/null
@@ -0,0 +1,16 @@
+// Unit Test Framework Includes
+#include "UnitTest++.h"
+#include <cstdlib>
+#include <iostream>
+
+// File To Test
+#include "tree.h"
+
+using namespace UnitTest;
+
+//-----------------------------------------------------------------------------
+// Begin Unit Tests
+//-----------------------------------------------------------------------------
+namespace {
+
+}