/*
version: 1.0
author: hellogiser
blog: http://www.cnblogs.com/hellogiser
date: 2014/9/18
*/
// binary tree node struct
struct BinaryTreeNode
{
int value;
BinaryTreeNode *parent; // for rank of bst
BinaryTreeNode *left;
BinaryTreeNode *right;
int size; // for kmin of bst
// x.size = x.left.size + x.right.size +1
};
int node_size(BinaryTreeNode *node)
{
// get node size of node
if (node == NULL)
return 0;
node->size = node_size(node->left) + node_size(node->right) + 1;
return node->size;
}
int left_size(BinaryTreeNode *node)
{
// get left size of node in o(1)
return node->left != NULL ? node->left->size : 0;
}
//=================================================
// BST Tree kmin
//=================================================
BinaryTreeNode *kmin_bst(BinaryTreeNode *root, int k)
{
if (root == NULL)
return NULL;
int pk = left_size(root) + 1; // get node rank first
if (k == pk)
{
return root;
}
else if (k < pk)
{
return kmin_bst(root->left, k);
}
else // k>pk
{
return kmin_bst(root->right, k - pk);
}
}
BinaryTreeNode *Kmin_of_BST(BinaryTreeNode *root, int k)
{
if (root == NULL)
return NULL;
// get node size of bst first
int nodes = node_size(root);
if (k < 1 || k > nodes)
return NULL;
// use node size info to get kmin of bst
return kmin_bst(root, k);
}
//=================================================
// BST Tree querying
//=================================================
BinaryTreeNode *Search_of_BST(BinaryTreeNode *root, int key)
{
if (root == NULL)
return NULL;
if (key == root->value)
return root;
else if(key < root->value)
return Search_of_BST(root->left, key);
else
return Search_of_BST(root->right, key);
}
BinaryTreeNode *Search_of_BST2(BinaryTreeNode *root, int key)
{
BinaryTreeNode *node = root;
while (node != NULL && key != node->value)
{
if (key < node->value)
node = node->left;
else
node = node->right;
}
return node;
}
BinaryTreeNode *Min_of_BST(BinaryTreeNode *root)
{
if (root == NULL)
return NULL;
BinaryTreeNode *node = root;
while(node->left != NULL)
node = node->left;
return node;
}
BinaryTreeNode *Max_of_BST(BinaryTreeNode *root)
{
if(root == NULL)
return NULL;
BinaryTreeNode *node = root;
while(node->right != NULL)
node = node->right;
return node;
}
/*
x has right child ===> Min(x.right) (case 1)
else px = x.parent (case 2)
if px.right == x ===> go up until px==null (case 2.2)
else px.left ==x ===> px (case 2.1)
*/
BinaryTreeNode *Successor(BinaryTreeNode *x)
{
if(x == NULL)
return NULL;
// case 1
if (x->right != NULL)
return Min_of_BST(x->right);
// case 2
BinaryTreeNode *px = x->parent;
if(px == NULL)
return NULL;
// case 2.1
if (px->left == x)
return px;
// case 2.2
while(px != NULL && px->right == x)
{
x = px;
px = px->parent;
}
return px;
}
/*
px px
/ \
x x
*/
/*
get all node size first
rank = leftsize(x)+1
px = x.parent
if px.right ==x ====> rank += leftsize(px)+1, go up
else rank += 0
*/
int Rank_of_BST(BinaryTreeNode *root, BinaryTreeNode *x)
{
if(root == NULL || x == NULL)
return -1;
// get node size first
node_size(root);
int rank = left_size(x) + 1;
// parent‘s left or right child ?
BinaryTreeNode *px = x->parent;
while(px != NULL)
{
if (px->right == x)
{
// px‘s right child
rank += left_size(px) + 1;
}
px = px->parent;
}
return rank;
}
|