详解线索二叉树

遍历二叉树是对非线性结构进行线性化操作,在得到的访问序列中,每个结点都只有一个直接前驱和一个直接后继。(除区头尾两个结点)

引入线索二叉树可以加快查找前驱与后继结点的速度,实质就是将二叉链表中的空指针改为指向前驱或后继的线索,线索化就是在遍历中修改空指针。

通常规定:对某一结点,若无左子树,将lchild指向前驱结点;若无右子树,将rchild指向后继结点。

还需要设置左右两个tag,用来标记当前结点是否有子树。

若ltag==1,lchild指向结点前驱;若rtag==1,rchild指向结点后继。

线索二叉树的存储结构如下:

typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild, *rchild;
int ltag, rtag;
}ThreadNode, *ThreadTree;


首先建立一棵二叉树,默认输入是按照先序遍历:

void CreateThreadTree(ThreadTree &T)
{
char c;
cin >> c;
if('#' == c)
T = NULL;
else{
T = new ThreadNode;
T->data = c;
CreateThreadTree(T->lchild);
CreateThreadTree(T->rchild);
}
}


现在我们通过中序遍历建立中序线索二叉树,即对给定的二叉树,递归进行线索化操作:

void CreateInThread(ThreadTree T)
{
ThreadTree pre = NULL;
if(T != NULL)
{
InThread(T, pre);               //对非空二叉树线索化
pre->rchild = NULL;             //处理遍历的最后一个结点
pre->rtag = 1;
}
}


其中通过中序遍历对二叉树线索化的递归算法为:

void InThread(ThreadTree &p, ThreadTree &pre)    //pre始终指向中序遍历时上一个刚刚访问过的结点;
{
if(p != NULL)
{
InThread(p->lchild, pre);          //递归线索化左子树;
if(p->lchild == NULL)           //左子树为空,建立前驱线索;
{
p->lchild = pre;
p->ltag = 1;
}
if(pre != NULL && pre->rchild == NULL) //建立前驱结点的后继线索;
{
pre->rchild = p;
pre->rtag = 1;
}
pre = p;               //标记当前结点成为刚刚访问过的结点;
InThread(p->rchild, pre);       //递归线索化右子树;
}
}

线索二叉树已经构造完成。现在利用线索二叉树,可以实现二叉树遍历的非递归算法。以中序遍历为例:

要实现中序遍历,可以先求出中序线索二叉树的中序序列中第一个结点,然后调用求某个结点的后继结点算法,直到遍历完成。

求中序线索二叉树的中序序列中第一个结点算法:

ThreadNode *FirstNode(ThreadNode *p)
{
while(p->ltag != 1)         //如果有左孩子,迭代至左孩子
p = p->lchild;
return p;
}

求中序线索二叉树中序序列中某个结点的后继结点算法:

ThreadNode *NextNode(ThreadNode *p)
{
if(p->rtag != 1)            //如果有右孩子,则该结点的后继结点为该结点右子树在中序序列中的第一个结点;
return FirstNode(p->rchild);
else
return p->rchild;         //如果没有右孩子,直接返回后继结点;
}

最后,实现中序遍历:

void InOrderThread(ThreadNode *T)
{
for(ThreadNode *p = FirstNode(T); p!= NULL; p = NextNode(p))
{
cout << p->data << " ";
}
}

主函数如下:

int main()
{
ThreadTree T;            //定义一颗二叉树;
CreateThreadTree(T);        //构造二叉树;
CreateInThread(T);         //对二叉树线索化;
InOrderThread(T);         //对线索二叉树实现非递归的中序遍历;
return 0;
}

运行结果如图所示:


详解线索二叉树_第1张图片

你可能感兴趣的:(详解线索二叉树)