#ifndef H_BTree_
#define H_BTree_
#include <string>
#include <iostream>
using namespace std;
class Node{
friend class Tree;
private:
int key_;
string data_;
Node * lchild;
Node * rchild;
public:
Node(string data,int key):data_(data),key_(key){
lchild=rchild=NULL;
}
~Node(){
//cout<<"delete element:"<<data_<<" and key :"<<key_<<endl;
}
};
class Tree
{
private:
Node * root_;
public:
Tree(){
root_=NULL;
}
~Tree();
bool Insert(const string data,int key);
Node * Find(int key,string & data) const;
bool Tranverse() const;
bool Delete(int key,string & data);
int Length() const;
private:
bool InsertRoot(Node * root){
root_=root;
return true;
}
bool TranverseNode(Node * ptr) const;
//forbid the copy constructor
Tree(const Tree & other);
//forbid the assignment
Tree * operator=(const Tree & other);
void DeleteNode(Node * node);
void Measure(Node * node,int & depth) const;
};
Tree::~Tree()
{
DeleteNode(root_);
}
//insert an node into the tree
bool Tree::Insert(const string data, int key)
{
string temp;
if(Find(key,temp))
return false;
Node * element=new Node(data,key);
if(root_==NULL)
return InsertRoot(element);
Node * ptr=root_;
Node * pos=NULL;
bool ifLeft=false;
while(ptr!=NULL)
{
pos=ptr;
if(ptr->key_>key)
{
ptr=ptr->lchild;
ifLeft=true;
}
else
{
ptr=ptr->rchild;
ifLeft=false;
}
}
if(ifLeft)
pos->lchild=element;
else
pos->rchild=element;
return true;
}
//tranverse the tree
bool Tree::Tranverse() const
{
return TranverseNode(root_);
}
//tranverse the tree by recruive way
bool Tree::TranverseNode(Node * ptr) const
{
Node * temp=NULL;
if(ptr->lchild!=NULL)
TranverseNode(ptr->lchild);
cout<<ptr->key_<<" "<<ptr->data_<<endl;
if(ptr->rchild!=NULL)
TranverseNode(ptr->rchild);
return true;
}
//search the Node whick has the same key
//return the pointer to the node
Node * Tree::Find(int key,string & data) const
{
Node * ptr=root_;
// bool ifFind=false;
while(ptr!=NULL)
{
if(ptr->key_==key)
{
//ifFind=true;
break;
}
else if(ptr->key_>key)
ptr=ptr->lchild;
else
ptr=ptr->rchild;
}
//if(ifFind)
if(ptr)
{
data=ptr->data_;
return ptr;
}
return NULL;
}
bool Tree::Delete(int key, std::string &data)
{
if(!Find(key,data))
return false;
//first ,need to find the parent node
Node * ptr=root_;
Node * parentNode=root_;
bool ifLeft=false;
while(true) //must find the node
{
if(ptr->key_==key)
break;
parentNode=ptr;
if(ptr->key_<key)
{
ptr=ptr->rchild;
ifLeft=false;
}
else
{
ptr=ptr->lchild;
ifLeft=true;
}
}
data=ptr->data_;
//three conditions
//1.this node is a leaf
if(ptr->lchild==NULL && ptr->rchild==NULL)
{
//data=ptr->data_;
if(ptr==root_) //single root leaf
{
root_=NULL;
}
else
{
if(ifLeft)
parentNode->lchild=NULL;
else
parentNode->rchild=NULL;
}
}
else if(ptr->lchild==NULL ) //2.has a right child
{
if(ptr==root_)
root_=root_->rchild;
else if(ifLeft) //has a left child
parentNode->lchild=ptr->rchild;
else if(!ifLeft)
parentNode->rchild=ptr->rchild;
}
else if(ptr->rchild==NULL) //has a left child
{
if(ptr==root_)
root_=root_->lchild;
else if(ifLeft)
parentNode->lchild=ptr->lchild;
else if(!ifLeft)
parentNode->rchild=ptr->lchild;
}
else //has two child
{
if(ptr==root_)
{
root_=root_->lchild;
Node * temp=ptr->rchild;
while(temp->lchild!=NULL)
temp=temp->lchild;
temp->lchild=ptr->lchild->rchild;
root_->rchild=ptr->rchild;
}
else if(ifLeft)
{
parentNode->lchild=ptr->lchild;
Node * temp=ptr->rchild;
while(temp->lchild!=NULL)
temp=temp->lchild;
temp->lchild=ptr->lchild->rchild;
ptr->lchild->rchild=ptr->rchild;
}
else
{
parentNode->rchild=ptr->lchild;
Node * temp=ptr->rchild;
while(temp->lchild!=NULL)
temp=temp->lchild;
temp->lchild=ptr->lchild->rchild;
ptr->lchild->rchild=ptr->rchild;
}
}
delete ptr;
return true;
}
void Tree::DeleteNode(Node * node)
{
if(node->lchild!=NULL)
DeleteNode(node->lchild);
if(node->rchild!=NULL)
DeleteNode(node->rchild);
delete node;
return;
}
int Tree::Length() const
{
int depth=0;
Measure(root_,depth);
return depth;
}
void Tree::Measure(Node * node,int & depth) const
{
int ldepth=depth+1;
int rdepth=depth+1;
if(node->lchild==NULL && node->rchild==NULL)
{
depth+=1;
return;
}
if(node->lchild)
Measure(node->lchild,ldepth);
if(node->rchild)
Measure(node->rchild,rdepth);
depth=(ldepth>rdepth)?ldepth:rdepth;
return;
}
#endif H_BTree_