#include"splaytree.h"
#include
#include
splaytree_node* splaytree_allocnode(key_type key,int data)
{
splaytree_node *node = NULL;
node = (splaytree_node*)malloc(sizeof(splaytree_node));
if(node == NULL)
return NULL;
else
{
node->key = key;
node->data = data;
node->left = node->right = node->parent = NULL;
return node;
}
}
splaytree_node* splaytree_freenode(splaytree_node* node)
{
if(node)
{
free(node);
node = NULL;
}
}
static void rotate_right(splaytree_node* root)
{
assert(root && root->parent == NULL && root->left != NULL);
splaytree_node* left = NULL;
left = root->left;
root->left = left->right;
if(left->right)
left->right->parent = root;
root->parent = left;
left->parent = NULL;
left->right = root;
}
static void rotate_left(splaytree_node* root)
{
assert(root && root->parent == NULL && root->right != NULL);
splaytree_node *right = NULL;
right = root->right;
root->right = right->left;
if(right->left)
right->left->parent = root;
root->parent = right;
right->parent = NULL;
right->left = root;
}
/*make sure that tree is not empty,which mean tree's root is not null*/
int do_splay(key_type key,splaytree *tree)
{
splaytree_node subleft = {0,};
splaytree_node subright = {0,};
splaytree_node* psubleft = &subleft;
splaytree_node* psubright = &subright;
splaytree_node* root = tree->root;
int ret ;
for(;;)
{
ret = key - root->key;
if(ret == 0)
break;
if(ret < 0)
{
splaytree_node* left ;
left = root->left;
if( left == NULL)
break;
if(ret = (key - left->key)< 0)
{
rotate_right(root);
root = left;
left = left->left;
if(left == NULL)
break;
}
/* 右连接:将当前根及其右子树连接到右树上。*/
psubright->left = root;
root->parent = psubright;
psubright = root;
root->left = NULL;
/*左子结点作为新根*/
root = left;
root->parent = NULL;
}
else
{
splaytree_node* right;
right = root->right;
if(right == NULL)
break;
if(ret = (key - right->key) > 0 )
{
rotate_left(root);
root = right;
right = right->right;
if(right == NULL)
break;
}
/*左连接:将当前根及其左子树连接到左树上。*/
psubleft->right = root;
root->parent = psubleft;
psubleft = root;
root->right = NULL;
/*右子结点作为新根。*/
root = right;
root->parent = NULL;
}
}
psubleft->right = root->left;
if(root->left)
root->left->parent = psubleft;
psubright->left = root->right;
if(root->right)
root->right->parent = psubright;
root->left = subleft.right;
if(subleft.right)
subleft.right->parent = root;
root->right = subright.left;
if(subright.left)
subright.left->parent = root;
tree->root = root;
return ret;
}
splaytree_node* splaytree_lookup(key_type key,splaytree* tree)
{
if(tree->root == NULL)
return NULL;
if(do_splay(key,tree) != 0)
return NULL;
else
return tree->root;
}
int splaytree_insert(splaytree_node* node,splaytree *tree)
{
splaytree_node* root = NULL;
int res;
if(tree->root == NULL)
{
tree->root = node;
return 0;
}
res = do_splay(node->key,tree);
if(res == 0)
return -1;
root = tree->root;
if(res < 0)
{
splaytree_node *left;
left = root->left;
node->left = left;
if(left)
left->parent = node;
node->right = root;
root->parent = node;
root->left = NULL;
}
else
{
splaytree_node* right;
right = root->right;
node->right = right;
if(right)
right->parent = node;
node->left = root;
root->parent = node;
root->right = NULL;
}
tree->root = node;
return 0;
}
int splaytree_remove(key_type key,splaytree* tree)
{
splaytree_node *node;
node = splaytree_lookup(key,tree);
if(node == NULL)
return -1;
splaytree_node *left = tree->root->left;
splaytree_node *right = tree->root->right;
splaytree_freenode(node);
left->parent = NULL;
right->parent = NULL;
if(left == NULL)
{
tree->root = right;
return 0;
}
else
{
tree->root = left;
do_splay(key,tree);
tree->root->right = right;
if(right)
right->parent = tree->root;
return 0;
}
}