赞
踩
二叉树的遍历是以一定规则将二叉树中的结点排列成一个线性序列,从而得到二叉树的前序序列、中序序列、后序序列。这实质上是对一个非线性结构进行线性化操作。当以二叉链表作为存储结构时,只存储了结点的左右孩子信息,而没有存储结点在遍历序列中的前驱和后继信息。而要想获得这样的信息有两种方法:①遍历二叉树。在遍历过程中可得到结点的前驱和后继,但这种动态访问浪费时间;②充分利用二叉链表的空链域,将遍历过程中结点的前驱和后继信息保存下来。
在一棵有n个结点的二叉树中,共有2*n个指针域,其中有n+1个空指针域,可以利用这些空指针来指示其前驱和后继。
大量的空余指针能否利用起来?
指向前驱和后继的指针称为线索,加上线索的二叉链表就称为线索链表,相应的二叉树就称为线索二叉树
对二叉树以某种次序遍历使其变为线索二叉树的过程就叫做线索化
在遍历过程中,访问及诶点的操作是检查此结点的左右指针域是否为空,如果为空,将它改成指向其前驱或后继结点的线索。实现过程:设指针p指向当前结点,pre指向刚访问过的结点,即p的前驱;这样便于修改pre的后继线索和p的前驱线索。
结点代码实现:
- type struct BiThrNode{
- ElemType data;
- struct BiThrNode *lchild,*rchild;
- int ltag,rtag;
- }BiThrNode,*BiThrNode;
说明:
1、三种二叉树的线索化
(1)结点p的中序前驱结点
①若p的ltag=1,lchild指向其前驱;
②若p的ltag=0,p的前驱是以该结点为根的左子树上按中序遍历的最后一个结点。
(2)结点p的中序后继结点
①若p的rtag=1,rchild指向其后继;
②若p的rtag=0,p的后继是以该结点为根的右子树上按中序遍历的第一个结点。
(1)查找结点*p的前驱
若结点*p无左子树,则p->lchild指向其前驱
若结点*p有左子树,当其右子树为空时,其左子树的根(即p->lrchild)为其后序前驱。当其右子树非空时,其右子树的根(即p->rchild)为其后序前驱。
(2)查找结点*p的后继
若结点*p为根,则无后继;
若结点*p为其双亲的右孩子,则其后继为其双亲;
若结点*p为其双亲的左孩子,且双亲无右子女,则其后继为其双亲;
若结点*p为其双亲的左孩子,且双亲有右子女,则结点*p的后继是其双亲的右子树中按后序遍历的第一个结点。
所以,求后序线索二叉树中结点的后继要知道其双亲的信息,要使用栈,所以说后序线索二叉树是不完善的。
在先序线索二叉树中查找结点的后继较容易,而查找前驱要知道其双亲的信息,要使用栈,所以说先序线索二叉树也是不完善的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。