线索二叉树
线索链表
线索:将二叉链表中的空指针域指向前驱结点和后继结点的指针被称为线索;
线索化:使二叉链表中结点的空链域存放其前驱或后继信息的过程称为线索化;
线索二叉树:加上线索的二叉树称为线索二叉树。
结点结构:ltag data child rtag
ltag={
0: lchild指向该结点的左孩子
1: lchild指向该结点的前驱结点
}
rtag={
0: rchild指向该结点的右孩子
1: rchild指向该结点的后继结点
}
enum flag {Child, Thread};
template <class T>
struct ThrNode
{
T data;
ThrNode<T> *lchild, *rchild;
flag ltag, rtag;
};
template <class T>
class InThrBiTree{
public:
InThrBiTree();
~ InThrBiTree( );
ThrNode *Next(ThrNode<T> *p);
void InOrder(ThrNode<T> *root);
private:
ThrNode<T> *root;
ThrNode<T> * Creat();
void ThrBiTree(ThrNode<T> *root);
};
template <class T>ThrNode<T>* InThrBiTree<T>::Creat( ){
ThrNode<T> *root;
T ch;
cout<<"请输入创建一棵二叉树的结点数据"<<endl;
cin>>ch;
if (ch=="#") root = NULL;
else{
root=new ThrNode<T>;
root->data = ch;
root->ltag = Child; root->rtag = Child;
root->lchild = Creat( );
root->rchild = Creat( );
}
return root;
}
中序线索化二叉树:递归实现
基本思想:
在遍历的过程中完成线索化
可以采用前序、中序、后序遍历建立前序线索二叉树、中序线索二叉树和后序线索二叉树。
中序线索二叉树的构造方法
中序线索化根结点的左子树;
对根结点进行线索化;
中序线索化根结点的右子树;
template <class T> void ThrBiTree<T>::ThrBiTree (ThrNode<T>*root) {
if (root==NULL) return; //递归结束条件
ThrBiTree(root->lchild);
if (!root->lchild){ //对root的左指针进行处理
root->ltag = Thread;
root->lchild = pre; //设置pre的前驱线索
}
if (!root->rchild) root->rtag = Thread;
if(pre != NULL){
if (pre->rtag==Thread) pre->rchild = root;
}
pre = root;
ThrBiTree(root->rchild);
}
线索二叉树的建立
template <class T>
InThrBiTree<T>::InThrBiTree( )
{
//ThrNode<T>* pre = NULL;
this->root = Creat( );
ThrBiTree(root);
}
在中序线索树中查找结点的中序遍历的后继
template <class T> ThrNode<T>* InThrBiTree<T>::Next(ThrNode<T>* p)
{
ThrNode<T>* q; //要查找的p的后继
if (p->rtag==Thread) q = p->rchild;
else{
q = p->rchild;
while (q->ltag==Child) {
q = q->lchild;
}
}
return q;
}
线索链表的遍历算法:中序遍历中序线索树
template <class T>
void InThrBiTree<T>::InOrder(ThrNode<T> *root){
ThrNode<T>* p = root;
if (root==NULL) return;
while (p->ltag==Child) { p = p->lchild; }
cout<<p->data<<" ";
while (p->rchild!=NULL) {
p = Next(p);
cout<<p->data<<" ";
}
cout<<endl;
}