Initial implementation of Btree
This commit is contained in:
parent
f30f7a6449
commit
98bea5b32a
3 changed files with 121 additions and 9 deletions
2
Makefile
2
Makefile
|
|
@ -1,7 +1,7 @@
|
||||||
IHCT_CFLAGS=-Wall -Wextra -Wpedantic -Wfatal-errors -std=gnu99 -fPIC -shared
|
IHCT_CFLAGS=-Wall -Wextra -Wpedantic -Wfatal-errors -std=gnu99 -fPIC -shared
|
||||||
TEST_CFLAGS=-Wall -Wextra -Wpedantic -Wfatal-errors -DIHCT_SHORT -L./ -Wl,-rpath ./
|
TEST_CFLAGS=-Wall -Wextra -Wpedantic -Wfatal-errors -DIHCT_SHORT -L./ -Wl,-rpath ./
|
||||||
|
|
||||||
tests: tests.c list.h libihct.so
|
tests: tests.c list.h tree.h libihct.so
|
||||||
gcc $(TEST_CFLAGS) tests.c -lihct -o tests
|
gcc $(TEST_CFLAGS) tests.c -lihct -o tests
|
||||||
|
|
||||||
libihct.so: ihct/vector.c ihct/ihct.c
|
libihct.so: ihct/vector.c ihct/ihct.c
|
||||||
|
|
|
||||||
126
tree.h
126
tree.h
|
|
@ -1,5 +1,7 @@
|
||||||
#ifndef TREE_H
|
#ifndef TREE_H
|
||||||
#define TREE_H
|
#define TREE_H
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
typedef struct tnode_ tnode_t;
|
typedef struct tnode_ tnode_t;
|
||||||
typedef struct tnode_* tnode_ptr;
|
typedef struct tnode_* tnode_ptr;
|
||||||
typedef enum { INT, UINT, CHAR, FLOAT, DOUBLE, CHAR_PTR, VOID_PTR } tnode_value_t;
|
typedef enum { INT, UINT, CHAR, FLOAT, DOUBLE, CHAR_PTR, VOID_PTR } tnode_value_t;
|
||||||
|
|
@ -12,21 +14,131 @@ typedef struct tnode_ {
|
||||||
char vc;
|
char vc;
|
||||||
float vf;
|
float vf;
|
||||||
double vd;
|
double vd;
|
||||||
char* vcp;
|
char *vcp;
|
||||||
void *vptr;
|
void *vptr;
|
||||||
};
|
};
|
||||||
tnode_ptr parent;
|
tnode_ptr parent;
|
||||||
tnode_ptr left_leaf;
|
tnode_ptr left_child;
|
||||||
tnode_ptr right_leaf;
|
tnode_ptr right_child;
|
||||||
} tnode_t;
|
} tnode_t;
|
||||||
|
|
||||||
|
int compare(int type, void *left, void *right)
|
||||||
tnode_t* tree_root(tnode_t* leaf)
|
|
||||||
{
|
{
|
||||||
tnode_t* current = leaf;
|
switch (type)
|
||||||
|
{
|
||||||
|
case INT:
|
||||||
|
return *((int*)left) - *((int*)right);
|
||||||
|
case UINT:
|
||||||
|
return *((unsigned int*)left) - *((unsigned int*)right);
|
||||||
|
case FLOAT:
|
||||||
|
return *((float*)left) - *((float*)right);
|
||||||
|
case DOUBLE:
|
||||||
|
return *((float*)left) - *((float*)right);
|
||||||
|
case CHAR_PTR:
|
||||||
|
return strcmp((char*)left, (char*)right);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while(current = current->parent && current->parent);
|
tnode_t* btree_root(tnode_t *node)
|
||||||
|
{
|
||||||
|
tnode_t* current = node;
|
||||||
|
while((current = current->parent) && current->parent);
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void btree_insert(tnode_t *root, tnode_t *new_node)
|
||||||
|
{
|
||||||
|
tnode_t *current = root;
|
||||||
|
int rootdiff = compare(current->type, ¤t->vi, &new_node->vi);
|
||||||
|
bool left = current->left_child != NULL;
|
||||||
|
bool right = current->right_child != NULL;
|
||||||
|
|
||||||
|
if (!rootdiff) return;
|
||||||
|
|
||||||
|
if (left)
|
||||||
|
{
|
||||||
|
if (rootdiff < 0)
|
||||||
|
btree_insert(current->left_child, new_node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rootdiff < 0)
|
||||||
|
{
|
||||||
|
current->left_child = new_node;
|
||||||
|
new_node->parent = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (right)
|
||||||
|
{
|
||||||
|
if (rootdiff > 0)
|
||||||
|
btree_insert(current->right_child, new_node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rootdiff > 0)
|
||||||
|
{
|
||||||
|
current->right_child = new_node;
|
||||||
|
new_node->parent = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void btree_delete(tnode_t *root, void *data)
|
||||||
|
{
|
||||||
|
int rootdiff = compare(root->type, &root->vi, data);
|
||||||
|
bool left = root->left_child;
|
||||||
|
bool right = root->right_child;
|
||||||
|
tnode_t **position_in_parent_ptr = NULL;
|
||||||
|
if (root->parent && root->parent->left_child == root)
|
||||||
|
position_in_parent_ptr = &root->parent->left_child;
|
||||||
|
if (root->parent && root->parent->right_child == root)
|
||||||
|
position_in_parent_ptr = &root->parent->right_child;
|
||||||
|
|
||||||
|
if (rootdiff < 0 && left)
|
||||||
|
{
|
||||||
|
btree_delete(root->left_child, data);
|
||||||
|
}
|
||||||
|
if (rootdiff > 0 && right)
|
||||||
|
{
|
||||||
|
btree_delete(root->right_child, data);
|
||||||
|
}
|
||||||
|
if (!rootdiff)
|
||||||
|
{
|
||||||
|
if (left && !right)
|
||||||
|
{
|
||||||
|
root->left_child->parent = root->parent;
|
||||||
|
if (position_in_parent_ptr)
|
||||||
|
*position_in_parent_ptr = root->left_child;
|
||||||
|
}
|
||||||
|
if (!left && right)
|
||||||
|
{
|
||||||
|
root->right_child->parent = root->parent;
|
||||||
|
if (position_in_parent_ptr)
|
||||||
|
*position_in_parent_ptr = root->right_child;
|
||||||
|
}
|
||||||
|
if (left && right)
|
||||||
|
{
|
||||||
|
tnode_t *walker = root->right_child;
|
||||||
|
while (walker->left_child) walker = walker->left_child;
|
||||||
|
if (position_in_parent_ptr)
|
||||||
|
*position_in_parent_ptr = walker;
|
||||||
|
walker->parent = root->parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tnode_t* btree_find(tnode_t *current, void *data)
|
||||||
|
{
|
||||||
|
int currentdiff = compare(current->type, ¤t->vi, data);
|
||||||
|
if (!currentdiff) return current;
|
||||||
|
if (currentdiff < 0)
|
||||||
|
if (current->left_child) btree_find(current->left_child, data);
|
||||||
|
else return NULL;
|
||||||
|
else
|
||||||
|
if (current->right_child) btree_find(current->right_child, data);
|
||||||
|
else return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#endif //TREE_H
|
#endif //TREE_H
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue