就是在中序遍历的时候加上线索,为了区分线索和孩子,要多加两个标志变量ltag,rtag如果标志为true就表明是线索,
如果为false就表示孩子;
一般规定是将做指针为空的指针域用来存放直接前驱;
将有指针为空的指针域用来存放直接后继;当然如果不为空的话就不会用来存放前后继,而是孩子了
意思就是存放前继的是左指针,存放后继的是右指针,一般规定这样写,
基本思路是新设两个结点,一个头结点Head,一个辅助结点pre;
头结点左指针指向根结点,右指针指向某种遍历顺序的最后一个结点,最后一个结点的右指针指向头结点
pre指针让其一直指向当前结点的直接前驱;
下面是凭感觉写的,给个思路和思想,没有测试,如果有错望指正:
typedef char Elem;
typedef struct Node
{
Elem data;
struct Node *lchild,*rchild;
bool rtag,ltag; //左右标记 true代表线索,false代表孩子
}*Tree;
void XianSuoTree(Tree T)
{
Tree Head,pre;
Head =new struct Node; //初始化头结点
pre =new struct Node;//初始化pre结点
Head->ltag=false; //初始化头结点左标志
Head->rtag=true;
Head->lrchild=T; //做指针指向根结点
head->rchild=head; //又指针回指
pre=Head; //是pre指针作为根结点的直接前驱
BianLi(T,pre); //中序遍历
pre->rtag=true; //将遍历中的最后一个结点右标志值为true
pre->lchild=Head; //最后一个结点右孩子指向头结点
Head->lchild=pre; //头结点的右孩子指向中序遍历的最后一个结点,使之具有循环线索关系
}
void BianLi(Tree p,Tree pre) //p为当前结点,pre为当前节点的直接前驱
{
BianLi(p->lchild,pre) //中序遍历左子树
if(!p->lchild) //判断做孩子情况,如果为空则将左指针指向其直接前驱
{
p->ltag=true;
p->lchild=pre;
}
if(!pre->rchild) //判断pre的右孩子情况,如果为空则将其有指针指向其直接后继
{
pre->rtag=true;
pre->rchild=p;
}
pre=p; //保证pre始终为当前结点的直接前驱
BianLi(p->rchild,pre); //中序遍历右子树
}