#include<iostream>
#include<cstdlib>
using namespace std;
enum Tag
{
THREAD,
LINK,
};
template<typename T>
struct TreeNode
{
T _data;
TreeNode<T>* _left;
TreeNode<T>* _right;
Tag _leftTag;
Tag _rightTag;
TreeNode(const T& t)
:_data(t)
,_left(NULL)
,_right(NULL)
,_leftTag(LINK)
,_rightTag(LINK)
{}
};
template<class T>
class Tree
{
typedef TreeNode<T> Node;
public:
Tree()
:_root(NULL)
{}
Tree(T* a,size_t size,const T& invalid)
{
size_t index=0;
_root=CreateTree(a,size,index,invalid);
}
void InOrder_ThreadTree()
{
Node* prev=NULL;
_InOrder_ThreadTree(_root,prev);
}
void InOrder()
{
_InOrder(_root);
}
void PrevOrder_ThreadTree()
{
Node* prev=NULL;
_PrevOrder_ThreadTree(_root,prev);
}
void PrevOrder()
{
_PrevOrder(_root);
}
void PostOrder_ThreadTree()
{
Node* prev=NULL;
_PostOrder_ThreadTree(_root,prev);
}
protected:
Node* CreateTree(T* a,size_t size,size_t& index,const T& invalid)
{
assert(a);
Node *root=NULL;
if((index<size)&&(a[index]!=invalid))
{
root = new Node(a[index]);
root->_left= CreateTree(a,size,++index,invalid);
root->_right= CreateTree(a,size,++index,invalid);
}
return root;
}
void _InOrder_ThreadTree(Node* root,Node* &prev)
{
if(root==NULL)
return ;
_InOrder_ThreadTree(root->_left,prev);
if(root->_left==NULL)
{
root->_leftTag=THREAD;
root->_left=prev;
}
if(prev&&prev->_right==NULL)
{
prev->_rightTag=THREAD;
prev->_right=root;
}
prev=root;
_InOrder_ThreadTree(root->_right,prev);
}
void _InOrder(Node* root)
{
if(root==NULL)
return ;
Node* cur=root;
while(cur)
{
while(cur->_leftTag==LINK)
{
cur=cur->_left;
}
cout<<cur->_data<<" ";
while(cur->_rightTag==THREAD)
{
cur=cur->_right;
cout<<cur->_data<<" ";
}
if(cur->_rightTag==LINK)
cur=cur->_right;
}
cout<<endl;
}
void _PrevOrder_ThreadTree(Node* root,Node* &prev)
{
if(root==NULL)
return;
if(root->_left==NULL)
{
root->_leftTag=THREAD;
root->_left=prev;
}
if(prev&&prev->_right==NULL)
{
prev->_rightTag=THREAD;
prev->_right=root;
}
prev=root;
if(root->_leftTag==LINK)
_PrevOrder_ThreadTree(root->_left,prev);
if(root->_rightTag==LINK)
_PrevOrder_ThreadTree(root->_right,prev);
}
void _PrevOrder(Node* cur)
{
if(cur==NULL)
return;
while(cur)
{
while(cur->_leftTag==LINK)
{
cout<<cur->_data<<" ";
cur=cur->_left;
}
cout<<cur->_data<<" ";
while(cur->_rightTag==THREAD)
{
cur=cur->_right;
cout<<cur->_data<<" ";
}
cur=cur->_right;
}
cout<<endl;
}
void _PostOrder_ThreadTree(Node* cur,Node* &prev)
{
if(cur==NULL)
return;
_PostOrder_ThreadTree(cur->_left,prev);
_PostOrder_ThreadTree(cur->_right,prev);
if(cur->_left==NULL)
{
cur->_leftTag=THREAD;
cur->_left=prev;
}
if(prev&&prev->_right==NULL)
{
prev->_rightTag=THREAD;
prev->_right=cur;
}
prev=cur;
}
private:
Node* _root;
};
int main()
{
int a1[10]={1,2,3,'#','#',4,'#','#',5,6};
Tree<int> t1 (a1,10,'#');
/*t1.InOrder_ThreadTree();
t1.InOrder();*/
t1. PostOrder_ThreadTree();
t1.PrevOrder();
system("pause");
return 0;
}