#include <iostream>
#include <iomanip>
#include <queue>
using namespace std;
template<typename T>
struct BinTreeNode
{
T data;
BinTreeNode<T> *leftchild;
BinTreeNode<T> *rightchild;
BinTreeNode(T x=T()):data(x),leftchild(NULL),rightchild(NULL){}
BinTreeNode(T x,BinTreeNode *l,BinTreeNode *r):data(x),leftchild(l),rightchild(r){}
};
template<typename T>
class BinaryTree
{
public:
BinaryTree():root(NULL){}
BinaryTree(T value):RefValue(value),root(NULL){}
BinaryTree(BinaryTree<T>& s)
{
RefValue=s.RefValue;
root=NULL;
Copy(root,s.root);
}
~BinaryTree()
{
_destory(root);
}
bool IsEmpty()
{
return (root==NULL);
}
BinTreeNode<T> *getCurrent(T& key)
{
return getCurrent(root,key);
}
T Parent(T key)
{
return vist(Parent(root,getCurrent(key)));
}
T LeftChild(T key)
{
return vist(getCurrent(key)->leftchild);
}
T RightChild(T key)
{
return vist(getCurrent(key)->rightchild);
}
int Height()
{
return Height(root);
}
int Size()
{
return Size(root);
}
T vist(BinTreeNode<T> *t)
{
if(t!=NULL)
{
return t->data;
}
return (T)0;
}
BinTreeNode<T> *getRoot()const;
void preOrder()
{
preOrder(root);
}
void inOrder()
{
inOrder(root);
}
void pastOrder()
{
pastOrder(root);
}
void leveOrder()
{
leveOrder(root);
}
BinTreeNode<T> *Find(T& item)const
{
return getCurrent(item);
}
void create_string(const char *str)
{
create_string(root,str);
}
private:
void leveOrder(BinTreeNode<T>* t)
{
queue<BinTreeNode<T> *> Q;
if(t==NULL)
{
return;
}
Q.push(t);
while(!Q.empty())
{
BinTreeNode<T> *p = Q.front();
Q.pop();
cout<<setw(4)<<vist(p);
if(p->leftchild!=NULL||p->rightchild!=NULL)
{
if(p->leftchild!=NULL)
Q.push(p->leftchild);
if(p->rightchild!=NULL)
Q.push(p->rightchild);
}
}
}
void _destory(BinTreeNode<T> *&t)
{
if(t==NULL)
{
return;
}
else
{
_destory(t->leftchild);
_destory(t->rightchild);
delete t;
}
}
void Copy(BinTreeNode<T>* &t,BinTreeNode<T> *&s)//这里必须是引用传递,因为深拷贝不存在.
{
if(s==NULL)
{
t==NULL;
return;
}
t = new BinTreeNode<T>(s->data);
Copy(t->leftchild,s->leftchild);
Copy(t->rightchild,s->rightchild);
}
BinTreeNode<T>* Parent(BinTreeNode<T>* t ,BinTreeNode<T> *current)
{
if(t==NULL)
{
return NULL;
}
if((t->leftchild==current)||(t->rightchild==current))
return t;
BinTreeNode<T> *save = Parent(t->leftchild,current);
if(save!=NULL)
{
return save;
}
Parent(t->rightchild,current);
}
BinTreeNode<T>* getCurrent(BinTreeNode<T>* t ,T key)
{
if(t==NULL)
{
return NULL;
}
if(vist(t)==key)
return t;
else
{
BinTreeNode<T> *save = getCurrent(t->leftchild,key);
if(save!=NULL)
{
return save;
}
getCurrent(t->rightchild,key);
}
}
int Size(BinTreeNode<T> *t)
{
if(t==NULL)
{
return 0;
}
return Size(t->leftchild)+Size(t->rightchild)+1;
}
int Height(BinTreeNode<T> *t)
{
if(t==NULL)
{
return 0;
}
int l = Height(t->leftchild)+1;
int r = Height(t->rightchild)+1;
return l>r?l:r;
}
void preOrder(BinTreeNode<T> *t)
{
if(t!=NULL)
{
cout<<setw(4)<<vist(t);
preOrder(t->leftchild);
preOrder(t->rightchild);
}
}
void pastOrder(BinTreeNode<T> *t)
{
if(t!=NULL)
{
pastOrder(t->leftchild);
pastOrder(t->rightchild);
cout<<setw(4)<<vist(t);
}
}
void inOrder(BinTreeNode<T> *t)
{
if(t!=NULL)
{
inOrder(t->leftchild);
cout<<setw(4)<<vist(t);
inOrder(t->rightchild);
}
}
void create_string(BinTreeNode<T>*& t,const char *& s)
{
if(*s==RefValue)
{
t=NULL;
return;
}
else
{
t=new BinTreeNode<T>(*s);
create_string(t->leftchild,++s);
create_string(t->rightchild,++s);
}
}
protected:
BinTreeNode<T> *root;
T RefValue;
};
int main()
{
BinaryTree<char> bt('#');
const char *str="ABC##DE##F##G#H##";
bt.create_string(str);
bt.inOrder();
cout<<endl;
bt.pastOrder();
cout<<endl;
bt.preOrder();
cout<<endl;
cout<<bt.Height()<<endl;
cout<<bt.Size()<<endl;
cout<<bt.LeftChild('B')<<endl;
cout<<"--------------------------------------"<<endl;
BinaryTree<char> bc=bt;
// bc.preOrder();
bc.leveOrder();
// cout<<bt.RightChild('H')<<endl;
return 0;
}