1.二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或用栈辅助实现非递归的遍历,用二叉树作为存储结构时,取到一个节点,只能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱和后继。
2.为了保存这种在遍历中需要的信息,我们利用二叉树中指向左右子树的空指针来存放节点的前驱和后继信息。
创建节点:
enum PointerTag
{
THREAD,
LINK,
};
template<class T>
struct BinaryTreeThdNode
{
T _data; //数据
BinaryTreeThdNode<T>* _letf; //左孩子
BinaryTreeThdNode<T>* _right; //右孩子
PointerTag _letfTag; //左孩子线索标志
PointerTag _rightTag; //右孩子线索标志
BinaryTreeThdNode(const T& data)
:_data(data)
,_letf(NULL)
,_right(NULL)
{}
};
线索化过程和遍历:
template<class T>
class BinaryTreeThd
{
typedef BinaryTreeThdNode<T> Node;
public:
typedef BinaryTreeThdIterator<T,T&,T*> Iterator;
BinaryTreeThd();
BinaryTreeThd(const T* a,size_t size,const T& invalid)
:_root(NULL)
{
size_t index=0;
_root=_GreateTree(a,size,index,invalid);
}
void InorderThd() //中序线索化
{
Node* prev=NULL;
_InoderThd(_root,prev);
}
void prevorderThd() //前序线索化
{
Node* prev=NULL;
_prevorderThd(_root,prev);
}
void PostOrderThd() //后序线索化
{
Node* prev=NULL;
_PostOrderThd(_root,prev);
}
void prevorder() //线索化后前序遍历
{
_prevorder(_root);
cout<<endl;
}
void Inorder() //线索化后中序遍历
{
_Inorder(_root);
cout<<endl;
}
void Postorder() //线索化后后序遍历
{
Node* cur=_root;
Node* prev=NULL;
while(cur)
{
//找最左边节点
while(cur&&cur->_letfTag ==LINK)
{
cur=cur->_letf ;
}
//访问后继
while(cur&&cur->_rightTag ==THREAD)
{
cout<<cur->_data <<" ";
prev=cur;
}
cur=cur->_right ;
}
}
protected:
void _PostOrderThd(Node* root,Node*& prev)
{
if(root==NULL)
return;
_PostOrderThd(root->_letf ,prev);
_PostOrderThd(root->_right ,prev);
if(root->_letf ==NULL)
{
root->_letfTag =THREAD;
root->_letf =prev;
}
if(prev&&prev->_right ==NULL)
{
prev->_rightTag =THREAD;
prev->_right =root;
}
prev=root;
}
void _prevorder(Node* root)
{
while(root)
{
while(root&&root->_letfTag ==LINK)
{
cout<<root->_data <<" ";
root=root->_letf ;
}
cout<<root->_data <<" ";
root=root->_right ;
}
}
void _prevorderThd(Node* root,Node* &prev)
{
if(root==NULL)
return;
if(root->_letf ==NULL)
{
root->_letfTag =THREAD;
root->_letf =prev;
}
if(prev&&(prev->_right ==NULL))
{
prev->_rightTag =THREAD;
prev->_right =root;
}
prev=root;
if(root->_letfTag ==LINK)
_prevorderThd(root->_letf ,prev);
if(root->_rightTag ==LINK)
_prevorderThd(root->_right ,prev);
}
void _Inorder(Node* root)
{
while(root)
{
//找左节点
while(root&&root->_letfTag==LINK)
{
root=root->_letf ;
}
cout<<root->_data <<" ";
//
while(root->_rightTag ==THREAD&&root->_right )
{
root=root->_right ;
cout<<root->_data <<" ";
}
root=root->_right ;
}
}
void _InoderThd(Node* root,Node* &prev)
{
if(root==NULL)
return;
_InoderThd(root->_letf ,prev); //zuo
if(root->_letf ==NULL)
{
root->_letfTag =THREAD;
root->_letf =prev;
}
if(root->_right ==NULL)
root->_rightTag =THREAD;
if(prev&&prev->_rightTag ==THREAD)
prev->_right =root;
prev=root;
_InoderThd(root->_right ,prev); //you
}
Node* _GreateTree(const T *a,size_t size,size_t& index,const T& invalid)
{
Node* root=NULL;
if(a[index]!=invalid&&index<size)
{
root=new Node(a[index]);
root->_letfTag =LINK;
root->_rightTag =LINK;
root->_letf =_GreateTree(a,size,++index,invalid);
root->_right =_GreateTree(a,size,++index,invalid);
}
return root;
}
private:
Node* _root;
};
void TestBinaryTreeThd()
{
int a[10]={1,2,3,'#','#',4,'#','#',5,6};
BinaryTreeThd<int> t(a,10,'#');
t.InorderThd ();
t.Inorder ();
//t.prevorderThd ();
//t.prevorder ();
//t.PostOrderThd ();
}