2015-03-16 02:02:45 +00:00
|
|
|
#include "avl_tree.h"
|
2015-02-21 10:47:24 +00:00
|
|
|
|
2016-05-22 01:54:29 +00:00
|
|
|
static inline int32_t SAPI _avl_tree_node_get_height(avl_tree_entry_t *node)
|
2015-02-21 10:47:24 +00:00
|
|
|
{
|
2015-03-01 09:11:58 +00:00
|
|
|
return node == NULL ? -1 : node->height;
|
2015-02-21 10:47:24 +00:00
|
|
|
}
|
|
|
|
|
2016-05-22 01:54:29 +00:00
|
|
|
static inline int32_t SAPI _avl_tree_node_get_balance_factor(avl_tree_entry_t *node)
|
2015-02-21 10:47:24 +00:00
|
|
|
{
|
2015-03-01 09:11:58 +00:00
|
|
|
if (node == NULL)
|
|
|
|
return 0;
|
2015-03-21 21:17:38 +00:00
|
|
|
return _avl_tree_node_get_height(node->left) - _avl_tree_node_get_height(node->right);
|
2015-02-21 10:47:24 +00:00
|
|
|
}
|
|
|
|
|
2016-05-20 19:07:11 +00:00
|
|
|
static avl_tree_entry_t *SAPI _avl_tree_node_right_rotate(avl_tree_entry_t *root)
|
2015-02-21 10:47:24 +00:00
|
|
|
{
|
2016-05-20 19:07:11 +00:00
|
|
|
avl_tree_entry_t *left_children = root->left;
|
2015-03-01 09:11:58 +00:00
|
|
|
//adjust parents first
|
|
|
|
left_children->parent = root->parent;
|
|
|
|
root->parent = left_children;
|
|
|
|
if (left_children->right != NULL)
|
|
|
|
left_children->right->parent = root;
|
|
|
|
//perform rotation
|
|
|
|
root->left = root->left->right;
|
|
|
|
left_children->right = root;
|
|
|
|
//adjust height
|
2016-05-17 19:03:18 +00:00
|
|
|
root->height = max_32(_avl_tree_node_get_height(root->left), _avl_tree_node_get_height(root->right)) + 1;
|
|
|
|
left_children->height = max_32(_avl_tree_node_get_height(left_children->left), _avl_tree_node_get_height(left_children->right)) + 1;
|
2015-03-01 09:11:58 +00:00
|
|
|
return left_children;
|
2015-02-21 10:47:24 +00:00
|
|
|
}
|
|
|
|
|
2016-05-20 19:07:11 +00:00
|
|
|
static avl_tree_entry_t *SAPI _avl_tree_node_left_rotate(avl_tree_entry_t *root)
|
2015-02-21 10:47:24 +00:00
|
|
|
{
|
2016-05-20 19:07:11 +00:00
|
|
|
avl_tree_entry_t *right_children = root->right;
|
2015-03-01 09:11:58 +00:00
|
|
|
//adjust parents
|
|
|
|
right_children->parent = root->parent;
|
|
|
|
root->parent = right_children;
|
|
|
|
if (right_children->left != NULL)
|
|
|
|
right_children->left->parent = root;
|
|
|
|
//perform rotation
|
|
|
|
root->right = root->right->left;
|
|
|
|
right_children->left = root;
|
|
|
|
|
2016-05-17 19:03:18 +00:00
|
|
|
root->height = max_32(_avl_tree_node_get_height(root->left), _avl_tree_node_get_height(root->right)) + 1;
|
|
|
|
right_children->height = max_32(_avl_tree_node_get_height(right_children->left), _avl_tree_node_get_height(right_children->right)) + 1;
|
2015-03-01 09:11:58 +00:00
|
|
|
return right_children;
|
|
|
|
}
|
2015-02-21 10:47:24 +00:00
|
|
|
|
2016-05-20 19:07:11 +00:00
|
|
|
static avl_tree_entry_t *SAPI _avl_tree_node_balance(avl_tree_entry_t *node)
|
2015-03-01 09:11:58 +00:00
|
|
|
{
|
2016-05-22 01:54:29 +00:00
|
|
|
const int32_t bf = _avl_tree_node_get_balance_factor(node);
|
2015-02-21 10:47:24 +00:00
|
|
|
|
2015-03-01 09:11:58 +00:00
|
|
|
if (bf > 1)
|
|
|
|
{
|
2016-05-22 01:54:29 +00:00
|
|
|
const int32_t left_bf = _avl_tree_node_get_balance_factor(node->left);
|
2015-03-01 09:11:58 +00:00
|
|
|
if (left_bf >= 0)
|
|
|
|
//left left
|
2015-03-21 21:17:38 +00:00
|
|
|
return _avl_tree_node_right_rotate(node);
|
2015-03-01 09:11:58 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
//left right
|
2015-03-21 21:17:38 +00:00
|
|
|
node->left = _avl_tree_node_left_rotate(node->left);
|
|
|
|
return _avl_tree_node_right_rotate(node);
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (bf < -1)
|
|
|
|
{
|
2016-05-22 01:54:29 +00:00
|
|
|
const int32_t right_bf = _avl_tree_node_get_balance_factor(node->right);
|
2015-03-01 09:11:58 +00:00
|
|
|
if (right_bf <= 0)
|
|
|
|
{
|
|
|
|
// right right
|
2015-03-21 21:17:38 +00:00
|
|
|
return _avl_tree_node_left_rotate(node);
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// right left
|
2015-03-21 21:17:38 +00:00
|
|
|
node->right = _avl_tree_node_right_rotate(node->right);
|
|
|
|
return _avl_tree_node_left_rotate(node);
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return node;
|
2015-02-21 10:47:24 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-05-22 01:54:29 +00:00
|
|
|
static avl_tree_entry_t *SAPI _avl_tree_node_insert(avl_tree_entry_t *root, avl_tree_entry_t *node, int32_t(*compare)(avl_tree_entry_t *, avl_tree_entry_t *), avl_tree_entry_t *parent)
|
2015-03-16 02:02:45 +00:00
|
|
|
{
|
2016-05-22 01:54:29 +00:00
|
|
|
if (node == NULL || compare == NULL)
|
2015-03-01 09:11:58 +00:00
|
|
|
return root;
|
|
|
|
if (root == NULL)
|
|
|
|
{
|
2015-03-21 21:17:38 +00:00
|
|
|
node->parent = parent;
|
|
|
|
return node;
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
|
|
|
|
2016-05-22 01:54:29 +00:00
|
|
|
const int32_t comp = compare(root, node);
|
2015-03-01 09:11:58 +00:00
|
|
|
if (comp < 0)
|
2015-03-21 21:17:38 +00:00
|
|
|
root->right = _avl_tree_node_insert(root->right, node, compare, root);
|
2015-03-01 09:11:58 +00:00
|
|
|
else if (comp == 0)
|
|
|
|
return root;
|
2015-02-21 10:47:24 +00:00
|
|
|
else
|
2015-03-21 21:17:38 +00:00
|
|
|
root->left = _avl_tree_node_insert(root->left, node, compare, root);
|
2015-02-21 10:47:24 +00:00
|
|
|
|
2016-05-17 19:03:18 +00:00
|
|
|
root->height = max_32(_avl_tree_node_get_height(root->left), _avl_tree_node_get_height(root->right)) + 1;
|
2015-02-21 10:47:24 +00:00
|
|
|
|
2015-03-21 21:17:38 +00:00
|
|
|
return _avl_tree_node_balance(root);
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
2015-02-21 10:47:24 +00:00
|
|
|
|
2016-05-20 19:07:11 +00:00
|
|
|
static void _avl_tree_swap_nodes(avl_tree_entry_t *node1, avl_tree_entry_t *node2)
|
2015-03-01 09:11:58 +00:00
|
|
|
{
|
2015-03-21 21:17:38 +00:00
|
|
|
if (node1 == NULL || node2 == NULL)
|
|
|
|
return;
|
2016-05-20 19:07:11 +00:00
|
|
|
avl_tree_entry_t *parent = NULL;
|
|
|
|
avl_tree_entry_t *child = NULL;
|
|
|
|
avl_tree_entry_t *temp = NULL;
|
2015-03-21 21:17:38 +00:00
|
|
|
//swap node but does not change anything else other than node1,node2
|
|
|
|
if (node1->parent != NULL && node1->parent == node2)
|
2015-02-21 10:47:24 +00:00
|
|
|
{
|
2015-03-21 21:17:38 +00:00
|
|
|
parent = node2;
|
|
|
|
child = node1;
|
|
|
|
}
|
|
|
|
else if (node2->parent != NULL && node2->parent == node1)
|
|
|
|
{
|
|
|
|
parent = node1;
|
|
|
|
child = node2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parent != NULL && child != NULL)
|
|
|
|
{
|
|
|
|
//connected case
|
|
|
|
if(parent->parent != NULL)
|
2015-03-01 09:11:58 +00:00
|
|
|
{
|
2015-03-21 21:17:38 +00:00
|
|
|
if(parent->parent->left == parent)
|
|
|
|
parent->parent->left = child;
|
|
|
|
else
|
|
|
|
parent->parent->right = child;
|
|
|
|
}
|
|
|
|
//update left/right for parent
|
|
|
|
if(parent->left != NULL && child != parent->left)
|
|
|
|
{
|
|
|
|
parent->left->parent = child;
|
|
|
|
}
|
|
|
|
if(parent->right != NULL && child != parent->right)
|
|
|
|
{
|
|
|
|
parent->right->parent = child;
|
|
|
|
}
|
|
|
|
//update left/right for children
|
|
|
|
if(child->left != NULL)
|
|
|
|
child->left->parent = parent;
|
|
|
|
if(child->right != NULL)
|
|
|
|
child->right->parent = parent;
|
|
|
|
|
|
|
|
child->parent = parent->parent;
|
|
|
|
parent->parent = child;
|
|
|
|
if (child == parent->left)
|
|
|
|
{
|
2016-05-17 19:03:18 +00:00
|
|
|
/* parent
|
|
|
|
/ \
|
|
|
|
children */
|
2015-03-21 21:17:38 +00:00
|
|
|
parent->left = child->left;
|
|
|
|
child->left = parent;
|
|
|
|
|
|
|
|
temp = parent->right;
|
|
|
|
parent->right = child->right;
|
|
|
|
child->right = temp;
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
2015-03-21 21:17:38 +00:00
|
|
|
else
|
|
|
|
{
|
2016-05-17 19:03:18 +00:00
|
|
|
/* parent
|
|
|
|
/ \
|
|
|
|
children */
|
2015-03-21 21:17:38 +00:00
|
|
|
parent->right = child->right;
|
|
|
|
child->right = parent;
|
|
|
|
|
|
|
|
temp = parent->left;
|
|
|
|
parent->left = child->left;
|
|
|
|
child->left = temp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//not connected case
|
|
|
|
//adjust all the nodes other than node1,node2
|
|
|
|
if(node1->left != NULL)
|
|
|
|
node1->left->parent = node2;
|
|
|
|
if(node1->right != NULL)
|
|
|
|
node1->right->parent = node2;
|
|
|
|
|
|
|
|
if(node2->left != NULL)
|
|
|
|
node2->left->parent = node1;
|
|
|
|
if(node2->right != NULL)
|
|
|
|
node2->right->parent = node1;
|
|
|
|
|
|
|
|
if(node1->parent != NULL)
|
|
|
|
{
|
|
|
|
if(node1->parent->left == node1)
|
|
|
|
node1->parent->left = node2;
|
|
|
|
else
|
|
|
|
node1->parent->right = node2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(node2->parent != NULL)
|
|
|
|
{
|
|
|
|
if(node2->parent->left == node2)
|
|
|
|
node2->parent->left = node1;
|
|
|
|
else
|
|
|
|
node2->parent->right = node1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//adjust node1,node2
|
|
|
|
temp = node1->parent;
|
|
|
|
node1->parent = node2->parent;
|
|
|
|
node2->parent = temp;
|
|
|
|
|
|
|
|
temp = node1->left;
|
|
|
|
node1->left = node2->left;
|
|
|
|
node2->left = temp;
|
|
|
|
|
|
|
|
temp = node1->right;
|
|
|
|
node1->right = node2->right;
|
|
|
|
node2->right = temp;
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
2015-03-21 21:17:38 +00:00
|
|
|
|
|
|
|
//swap height
|
2016-05-22 01:54:29 +00:00
|
|
|
int32_t height = node1->height;
|
2015-03-21 21:17:38 +00:00
|
|
|
node1->height = node2->height;
|
|
|
|
node2->height = height;
|
2015-03-16 02:02:45 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-05-20 19:07:11 +00:00
|
|
|
static avl_tree_entry_t *SAPI _avl_tree_node_delete(avl_tree_entry_t *root, avl_tree_entry_t *node,
|
2016-05-22 01:54:29 +00:00
|
|
|
int32_t (*compare)(avl_tree_entry_t *, avl_tree_entry_t *))
|
2015-03-16 02:02:45 +00:00
|
|
|
{
|
2016-05-22 01:54:29 +00:00
|
|
|
if (root == NULL || node == NULL || compare == NULL)
|
2015-03-16 02:02:45 +00:00
|
|
|
return root;
|
2016-05-22 01:54:29 +00:00
|
|
|
const int32_t comp = compare(root, node);
|
2015-03-16 02:02:45 +00:00
|
|
|
if (comp < 0)
|
2016-05-17 19:03:18 +00:00
|
|
|
root->right = _avl_tree_node_delete(root->right, node, compare);
|
2015-03-16 02:02:45 +00:00
|
|
|
else if(comp > 0)
|
2016-05-17 19:03:18 +00:00
|
|
|
root->left = _avl_tree_node_delete(root->left, node, compare);
|
2015-03-01 09:11:58 +00:00
|
|
|
else
|
|
|
|
{
|
2015-03-16 02:02:45 +00:00
|
|
|
// node with only one child or no child
|
|
|
|
if( (root->left == NULL) || (root->right == NULL) )
|
2015-03-01 09:11:58 +00:00
|
|
|
{
|
2016-05-20 19:07:11 +00:00
|
|
|
avl_tree_entry_t *child = root->left != NULL ? root->left : root->right;
|
2015-03-16 02:02:45 +00:00
|
|
|
|
|
|
|
if(child == NULL)
|
|
|
|
{ // 0 child
|
|
|
|
root = NULL;
|
|
|
|
}
|
|
|
|
else // 1 child
|
2015-03-01 09:11:58 +00:00
|
|
|
{
|
2015-03-21 21:17:38 +00:00
|
|
|
child->parent = root->parent;
|
|
|
|
root = child;
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
|
|
|
}
|
2015-03-16 02:02:45 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// node with two children: Get the inorder successor (smallest
|
|
|
|
// in the right subtree)
|
2016-05-20 19:07:11 +00:00
|
|
|
avl_tree_entry_t *successor = root->right;
|
2015-03-21 21:17:38 +00:00
|
|
|
while(successor->left != NULL)
|
|
|
|
successor = successor->left;
|
|
|
|
//swap fields
|
2015-09-04 19:04:22 +00:00
|
|
|
_avl_tree_swap_nodes(successor, root);
|
2015-03-16 02:02:45 +00:00
|
|
|
|
2015-03-21 21:17:38 +00:00
|
|
|
// Detach the inorder successor
|
2016-05-17 19:03:18 +00:00
|
|
|
successor->right = _avl_tree_node_delete(successor->right, root, compare);
|
2015-03-16 02:02:45 +00:00
|
|
|
|
2015-03-21 21:17:38 +00:00
|
|
|
root = successor;
|
2015-03-16 02:02:45 +00:00
|
|
|
}
|
2015-02-21 10:47:24 +00:00
|
|
|
}
|
2015-03-16 02:02:45 +00:00
|
|
|
if (root == NULL)
|
|
|
|
return root;
|
2016-05-17 19:03:18 +00:00
|
|
|
root->height = max_32(_avl_tree_node_get_height(root->left), _avl_tree_node_get_height(root->right)) + 1;
|
2015-03-21 21:17:38 +00:00
|
|
|
root = _avl_tree_node_balance(root);
|
2015-03-16 02:02:45 +00:00
|
|
|
return root;
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
2015-02-21 10:47:24 +00:00
|
|
|
|
2016-05-20 19:07:11 +00:00
|
|
|
static avl_tree_entry_t *SAPI _avl_tree_node_search(avl_tree_entry_t *root, avl_tree_entry_t *node,
|
2016-05-22 01:54:29 +00:00
|
|
|
int32_t(*compare)(avl_tree_entry_t *, avl_tree_entry_t *))
|
2015-03-01 09:11:58 +00:00
|
|
|
{
|
2016-05-22 01:54:29 +00:00
|
|
|
if(root == NULL || compare == NULL)
|
2015-03-21 21:17:38 +00:00
|
|
|
return NULL;
|
2016-05-22 01:54:29 +00:00
|
|
|
const int32_t comp = compare(root, node);
|
2015-03-21 21:17:38 +00:00
|
|
|
if (comp < 0)
|
2016-05-17 19:03:18 +00:00
|
|
|
return _avl_tree_node_search(root->right, node, compare);
|
2015-03-21 21:17:38 +00:00
|
|
|
else if (comp == 0)
|
|
|
|
return root;
|
|
|
|
else
|
2016-05-17 19:03:18 +00:00
|
|
|
return _avl_tree_node_search(root->left, node, compare);
|
2015-02-21 10:47:24 +00:00
|
|
|
}
|
|
|
|
|
2016-05-20 19:07:11 +00:00
|
|
|
static void SAPI _avl_tree_node_init(avl_tree_entry_t * it)
|
2015-02-21 10:47:24 +00:00
|
|
|
{
|
2015-03-21 21:17:38 +00:00
|
|
|
if(it != NULL)
|
2015-03-01 09:11:58 +00:00
|
|
|
{
|
2015-03-21 21:17:38 +00:00
|
|
|
it->height = 0;
|
|
|
|
it->left = NULL;
|
|
|
|
it->right = NULL;
|
|
|
|
it->parent = NULL;
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
2015-03-16 02:02:45 +00:00
|
|
|
return;
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
2015-02-21 10:47:24 +00:00
|
|
|
|
2015-03-16 02:02:45 +00:00
|
|
|
|
2016-05-22 01:54:29 +00:00
|
|
|
avl_tree_entry_t *SAPI avl_tree_smallest(avl_tree_t *tree)
|
2015-03-01 09:11:58 +00:00
|
|
|
{
|
2016-05-20 19:07:11 +00:00
|
|
|
if (tree == NULL)
|
2015-03-01 09:11:58 +00:00
|
|
|
return NULL;
|
2016-05-20 19:07:11 +00:00
|
|
|
avl_tree_entry_t* entry = tree->root;
|
|
|
|
if(entry == NULL)
|
|
|
|
return NULL;
|
|
|
|
while (entry->left != NULL)
|
|
|
|
entry = entry->left;
|
|
|
|
return entry;
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
2015-02-21 10:47:24 +00:00
|
|
|
|
2016-05-20 19:07:11 +00:00
|
|
|
avl_tree_entry_t *SAPI avl_tree_largest(avl_tree_t *tree)
|
2015-03-01 09:11:58 +00:00
|
|
|
{
|
2016-05-20 19:07:11 +00:00
|
|
|
if (tree == NULL)
|
2015-03-01 09:11:58 +00:00
|
|
|
return NULL;
|
2016-05-20 19:07:11 +00:00
|
|
|
avl_tree_entry_t* entry = tree->root;
|
|
|
|
if(entry == NULL)
|
|
|
|
return NULL;
|
|
|
|
while (entry->right != NULL)
|
|
|
|
entry = entry->right;
|
|
|
|
return entry;
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
|
|
|
|
2015-03-21 21:17:38 +00:00
|
|
|
|
2016-05-20 19:07:11 +00:00
|
|
|
avl_tree_entry_t *SAPI avl_tree_larger(avl_tree_entry_t *it)
|
2015-03-01 09:11:58 +00:00
|
|
|
{
|
2015-03-21 21:17:38 +00:00
|
|
|
if (it == NULL)
|
|
|
|
return NULL;
|
2016-05-20 19:07:11 +00:00
|
|
|
avl_tree_entry_t * root = it;
|
2015-03-16 02:02:45 +00:00
|
|
|
if (root->right != NULL)
|
|
|
|
{
|
|
|
|
root = root->right;
|
|
|
|
while (root->left != NULL)
|
|
|
|
root = root->left;
|
2015-03-21 21:17:38 +00:00
|
|
|
return root;
|
2015-03-16 02:02:45 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (root->parent != NULL)
|
|
|
|
{
|
|
|
|
if (root->parent->left == root)
|
2015-03-21 21:17:38 +00:00
|
|
|
return root->parent;
|
2015-03-16 02:02:45 +00:00
|
|
|
root = root->parent;
|
|
|
|
}
|
2015-03-21 21:17:38 +00:00
|
|
|
return NULL;
|
2015-03-16 02:02:45 +00:00
|
|
|
}
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
|
|
|
|
2016-05-20 19:07:11 +00:00
|
|
|
avl_tree_entry_t *SAPI avl_tree_smaller(avl_tree_entry_t *it)
|
2015-03-01 09:11:58 +00:00
|
|
|
{
|
2015-03-21 21:17:38 +00:00
|
|
|
if (it == NULL)
|
|
|
|
return NULL;
|
2016-05-20 19:07:11 +00:00
|
|
|
avl_tree_entry_t * root = it;
|
2015-03-16 02:02:45 +00:00
|
|
|
if (root->left != NULL)
|
|
|
|
{
|
|
|
|
root = root->left;
|
|
|
|
while (root->right != NULL)
|
|
|
|
root = root->right;
|
2015-03-21 21:17:38 +00:00
|
|
|
return root;
|
2015-03-16 02:02:45 +00:00
|
|
|
}
|
2015-02-21 10:47:24 +00:00
|
|
|
else
|
|
|
|
{
|
2015-03-16 02:02:45 +00:00
|
|
|
while (root->parent != NULL)
|
2015-02-21 10:47:24 +00:00
|
|
|
{
|
2015-03-16 02:02:45 +00:00
|
|
|
if (root->parent->right == root)
|
2015-03-21 21:17:38 +00:00
|
|
|
return root->parent;
|
2015-03-16 02:02:45 +00:00
|
|
|
root = root->parent;
|
2015-02-21 10:47:24 +00:00
|
|
|
}
|
2015-03-21 21:17:38 +00:00
|
|
|
return NULL;
|
2015-02-21 10:47:24 +00:00
|
|
|
}
|
2015-03-01 09:11:58 +00:00
|
|
|
}
|
2015-02-21 10:47:24 +00:00
|
|
|
|
2016-05-22 01:54:29 +00:00
|
|
|
avl_tree_entry_t * SAPI avl_tree_search(avl_tree_t *tree, avl_tree_entry_t * node)
|
2015-03-21 21:17:38 +00:00
|
|
|
{
|
2016-05-22 01:54:29 +00:00
|
|
|
return _avl_tree_node_search(tree->root, node, tree->compare);
|
2015-03-21 21:17:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-22 01:54:29 +00:00
|
|
|
void SAPI avl_tree_insert(avl_tree_t *tree, avl_tree_entry_t* data)
|
2015-03-21 21:17:38 +00:00
|
|
|
{
|
2016-05-22 01:54:29 +00:00
|
|
|
if(tree != NULL && data != NULL)
|
2015-03-21 21:17:38 +00:00
|
|
|
{
|
2016-05-22 01:54:29 +00:00
|
|
|
tree->root = _avl_tree_node_insert(tree->root, data, tree->compare, NULL);
|
2015-03-21 21:17:38 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-05-22 01:54:29 +00:00
|
|
|
void SAPI avl_tree_delete(avl_tree_t *tree, avl_tree_entry_t *data)
|
2015-03-21 21:17:38 +00:00
|
|
|
{
|
2016-05-22 01:54:29 +00:00
|
|
|
if(tree != NULL && data != NULL)
|
2015-03-21 21:17:38 +00:00
|
|
|
{
|
2016-05-22 01:54:29 +00:00
|
|
|
tree->root = _avl_tree_node_delete(tree->root, data, tree->compare);
|
2015-03-21 21:17:38 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-05-20 19:07:11 +00:00
|
|
|
int32_t SAPI avl_tree_size(avl_tree_t *tree)
|
|
|
|
{
|
|
|
|
if(tree == NULL)
|
|
|
|
return -1;
|
|
|
|
if(tree->root == NULL)
|
|
|
|
return 0;
|
|
|
|
int32_t size= 0;
|
|
|
|
avl_tree_entry_t* entry = avl_tree_smallest(tree);
|
|
|
|
while(entry != NULL)
|
|
|
|
{
|
|
|
|
size++;
|
|
|
|
entry = avl_tree_larger(entry);
|
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2016-05-22 01:54:29 +00:00
|
|
|
void SAPI avl_tree_init(avl_tree_t * tree, int32_t (*compare)(avl_tree_entry_t*, avl_tree_entry_t*))
|
2015-03-21 21:17:38 +00:00
|
|
|
{
|
|
|
|
if(tree != NULL)
|
|
|
|
{
|
|
|
|
tree->root = NULL;
|
2016-05-22 01:54:29 +00:00
|
|
|
tree->compare = compare;
|
2015-03-21 21:17:38 +00:00
|
|
|
}
|
|
|
|
return;
|
2016-05-22 01:54:29 +00:00
|
|
|
}
|