]> git.mdlowis.com Git - projs/libcds.git/commitdiff
commit tests for tree
authorMike D. Lowis <mike@mdlowis.com>
Fri, 19 Apr 2013 01:37:34 +0000 (21:37 -0400)
committerMike D. Lowis <mike@mdlowis.com>
Fri, 19 Apr 2013 01:37:34 +0000 (21:37 -0400)
source/tree/tree.c
source/tree/tree.h
tests/test_tree.cpp

index 051ec9b06cb7c87204ce91cbbc46d1c67cceee95..324a3d26fab5c6ce3d37966a8aaf5c8cad40401b 100644 (file)
@@ -7,10 +7,12 @@
 #include <stdlib.h>
 #include "tree.h"
 
+#include <stdio.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->cmp_fn = (NULL == cmp_fn) ? &tree_cmp_ptrs : cmp_fn;
     tree->size = 0;
     tree->root = NULL;
     return tree;
@@ -37,7 +39,8 @@ int tree_cmp_ptrs(void* tval,void* fval)
 
 void tree_free(tree_t* tree, bool free_values)
 {
-    tree_free_node(tree->root, free_values);
+    if (NULL != tree->root)
+        tree_free_node(tree->root, free_values);
     free(tree);
 }
 
@@ -71,41 +74,49 @@ void tree_insert(tree_t* tree, void* value)
 {
     bool finished = false;
     tree_node_t* node = tree->root;
-    while(!finished)
+    if (node == NULL)
+    {
+        tree->root = tree_new_node( value );
+        tree->size++;
+    }
+    else
     {
-        switch (tree->cmp_fn(node->value, value))
+        while(!finished)
         {
-            // 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++;
+            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;
-                }
-                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;
+                    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;
+            }
         }
     }
 }
@@ -116,47 +127,51 @@ void* tree_at(tree_t* tree, void* value)
     tree_node_t* node = tree->root;
     while(node != NULL)
     {
-        switch (tree->cmp_fn(node->value, value))
+        int cmp_val = tree->cmp_fn(node->value, value);
+        if (0 == cmp_val)
+        {
+            ret_val = node->value;
+            node = NULL;
+        }
+        else
         {
-            case 0:
-                ret_val = node->value;
-                node = NULL;
-                break;
-
-            case -1:
-                node = node->right;
-                break;
-
-            case 1:
-                node = node->left;
-                break;
+            node = (-1 == cmp_val) ? node->right : node->left;
         }
     }
     return ret_val;
 }
 
-void tree_erase(tree_t* tree, void* value)
+void tree_erase(tree_t* tree, void* value, bool free_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;
-    //    }
-    //}
+    tree_node_t* prev_node = NULL;
+    tree_node_t* curr_node = tree->root;
+    while(curr_node != NULL)
+    {
+        int cmp_val = tree->cmp_fn(curr_node->value, value);
+        if (0 == cmp_val)
+        {
+            // Node to delete has no children
+            if ((curr_node->left == NULL) && (curr_node->right == NULL))
+            {
+                //tree_erase_leaf(prev_node,curr_node);
+            }
+            // Node to delete has two children
+            else if ((curr_node->left != NULL) && (curr_node->right != NULL))
+            {
+                //tree_erase_inner_node(prev_node,curr_node);
+            }
+            // Node only has one child
+            else
+            {
+                //tree_erase_node(prev_node,curr_node);
+            }
+        }
+        else
+        {
+            prev_node = curr_node;
+            curr_node = (-1 == cmp_val) ? curr_node->right : curr_node->left;
+        }
+    }
 }
 
 void tree_clear(tree_t* tree, bool free_values)
index 1fe68363ad7ad3d9e10067fd051a3627757824c3..5611be591121b6927b1c28fa76e3da171d7261be 100644 (file)
@@ -1,6 +1,6 @@
 /**
     @file tree.h
-    @brief An implementation of a binary tree.
+    @brief An implementation of a binary search tree.
     $Revision$
     $HeadURL$
 */
@@ -139,7 +139,7 @@ void* tree_at(tree_t* tree, void* 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);
+void tree_erase(tree_t* tree, void* value, bool free_value);
 
 /**
  * @brief Erase all values in the tree.
index 8e12564b5e25563c688bf221351d0f4828e41405..1459cdcdef6c3e608cc133c573a2ba5643351694 100644 (file)
@@ -1,7 +1,7 @@
 // Unit Test Framework Includes
 #include "UnitTest++.h"
 #include <cstdlib>
-#include <iostream>
+#include <cstdio>
 
 // File To Test
 #include "tree.h"
@@ -12,5 +12,197 @@ using namespace UnitTest;
 // Begin Unit Tests
 //-----------------------------------------------------------------------------
 namespace {
+    //-------------------------------------------------------------------------
+    // Test tree_new function
+    //-------------------------------------------------------------------------
+    TEST(Verify_tree_new_allocates_a_new_tree_with_default_compare_fn)
+    {
+        tree_t* tree = tree_new(NULL);
+        CHECK(tree != NULL);
+        CHECK(tree->cmp_fn != NULL);
+        CHECK(tree->size == 0);
+        CHECK(tree->root == NULL);
+        tree_free( tree, false );
+    }
 
+    TEST(Verify_tree_new_allocates_a_new_tree_with_provided_compare_fn)
+    {
+        tree_t* tree = tree_new( (tree_cmp_fn_t)0x1234 );
+        CHECK(tree != NULL);
+        CHECK(tree->cmp_fn == (tree_cmp_fn_t)0x1234);
+        CHECK(tree->size == 0);
+        CHECK(tree->root == NULL);
+        tree_free( tree, false );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test tree_new_node function
+    //-------------------------------------------------------------------------
+    TEST(Verify_tree_new_node_allocates_a_new_tree_node_with_the_given_value)
+    {
+        tree_node_t* node = tree_new_node((void*)0x1234);
+        CHECK( node->value == (void*)0x1234);
+        CHECK( node->left == NULL);
+        CHECK( node->right == NULL);
+        tree_free_node( node, false );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test tree_cmp_ptrs function
+    //-------------------------------------------------------------------------
+    TEST(Verify_tree_cmp_ptrs_returns_0_when_pointers_equal)
+    {
+        CHECK(0 == tree_cmp_ptrs((void*)0x1234,(void*)0x1234));
+    }
+
+    TEST(Verify_tree_cmp_ptrs_returns_negative_when_tree_pointer_is_less_than_free_pointer)
+    {
+        CHECK(-1 == tree_cmp_ptrs((void*)0x1234,(void*)0x1235));
+    }
+
+    TEST(Verify_tree_cmp_ptrs_returns_positive_when_tree_pointer_is_greater_than_free_pointer)
+    {
+        CHECK(1 == tree_cmp_ptrs((void*)0x1234,(void*)0x1233));
+    }
+
+    //-------------------------------------------------------------------------
+    // Test tree_empty function
+    //-------------------------------------------------------------------------
+    TEST(Verify_tree_empty_returns_true_if_tree_is_empty)
+    {
+        tree_t tree = { NULL, 0, NULL };
+        CHECK( true == tree_empty( &tree ) );
+    }
+
+    TEST(Verify_tree_empty_returns_false_if_tree_is_not_empty)
+    {
+        tree_t tree = { NULL, 1, NULL };
+        CHECK( false == tree_empty( &tree ) );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test tree_size function
+    //-------------------------------------------------------------------------
+    TEST(Verify_tree_size_returns_the_number_of_elements_in_the_tree)
+    {
+        tree_t tree = { NULL, 42, NULL };
+        CHECK( 42 == tree_size( &tree ) );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test tree_max_size function
+    //-------------------------------------------------------------------------
+    TEST(Verify_max_size_returns_the_maximum_number_of_elements_a_tree_can_hold)
+    {
+        CHECK( (size_t)-1 == tree_max_size() );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test tree_insert function
+    //-------------------------------------------------------------------------
+    TEST(Verify_tree_insert_inserts_the_value_in_the_empty_tree)
+    {
+        tree_t* tree = tree_new(NULL);
+        tree_insert(tree,(void*)0x1234);
+        CHECK( tree->root != NULL );
+        CHECK( tree->root->value == (void*)0x1234 );
+        CHECK( tree->root->left == NULL );
+        CHECK( tree->root->right == NULL );
+        CHECK( tree->size == 1 );
+        tree_free(tree,false);
+    }
+
+    TEST(Verify_tree_insert_inserts_the_value_as_a_left_child)
+    {
+        tree_t* tree = tree_new(NULL);
+        tree_insert(tree,(void*)0x1234);
+        tree_insert(tree,(void*)0x1233);
+
+        CHECK( tree->root->left != NULL );
+        tree_node_t* node = (tree_node_t*)tree->root->left;
+        CHECK( node->value == (void*)0x1233 );
+        CHECK( node->left == NULL );
+        CHECK( node->right == NULL );
+        CHECK( tree->size == 2 );
+
+        tree_free(tree,false);
+    }
+
+    TEST(Verify_tree_insert_inserts_the_value_as_a_right_child)
+    {
+        tree_t* tree = tree_new(NULL);
+        tree_insert(tree,(void*)0x1234);
+        tree_insert(tree,(void*)0x1235);
+
+        CHECK( tree->root->right != NULL );
+        tree_node_t* node = (tree_node_t*)tree->root->right;
+        CHECK( node->value == (void*)0x1235 );
+        CHECK( node->left == NULL );
+        CHECK( node->right == NULL );
+        CHECK( tree->size == 2 );
+
+        tree_free(tree,false);
+    }
+
+    TEST(Verify_tree_insert_does_nothing_when_identical_node_already_exists)
+    {
+        tree_t* tree = tree_new(NULL);
+        tree_insert(tree,(void*)0x1234);
+        tree_insert(tree,(void*)0x1234);
+        CHECK( tree->root != NULL );
+        CHECK( tree->root->value == (void*)0x1234 );
+        CHECK( tree->root->left == NULL );
+        CHECK( tree->root->right == NULL );
+        CHECK( tree->size == 1 );
+        tree_free(tree,false);
+    }
+
+    //-------------------------------------------------------------------------
+    // Test tree_at function
+    //-------------------------------------------------------------------------
+    TEST(Verify_tree_at_returns_the_item_if_found)
+    {
+        tree_t* tree = tree_new(NULL);
+        tree_insert(tree,(void*)0x1234);
+        tree_insert(tree,(void*)0x1233);
+        tree_insert(tree,(void*)0x1235);
+        CHECK( (void*)0x1234 == tree_at(tree,(void*)0x1234) );
+        tree_free(tree,false);
+    }
+
+    TEST(Verify_tree_at_returns_null_if_tem_not_found)
+    {
+        tree_t* tree = tree_new(NULL);
+        tree_insert(tree,(void*)0x1234);
+        tree_insert(tree,(void*)0x1233);
+        tree_insert(tree,(void*)0x1235);
+        CHECK( (void*)NULL == tree_at(tree,(void*)0x1236) );
+        tree_free(tree,false);
+    }
+
+    //-------------------------------------------------------------------------
+    // Test tree_erase function
+    //-------------------------------------------------------------------------
+    TEST(Verify_tree_erase_erases_the_node_with_the_matching_value)
+    {
+    }
+
+    //-------------------------------------------------------------------------
+    // Test tree_clear function
+    //-------------------------------------------------------------------------
+    TEST(Verify_tree_clear_erases_all_nodes_in_the_tree)
+    {
+        tree_t* tree = tree_new(NULL);
+        tree_insert(tree,(void*)0x1234);
+        tree_insert(tree,(void*)0x1233);
+        tree_insert(tree,(void*)0x1235);
+
+        tree_clear(tree,false);
+        CHECK(tree != NULL);
+        CHECK(tree->cmp_fn != NULL);
+        CHECK(tree->size == 0);
+        CHECK(tree->root == NULL);
+
+        tree_free(tree,false);
+    }
 }