【数据结构】线索二叉树及结点的前驱和后继查找

文章目录


前言

二叉树的遍历是以一定规则将二叉树中的结点排列成一个线性序列,从而得到二叉树的前序序列、中序序列、后序序列。这实质上是对一个非线性结构进行线性化操作。当以二叉链表作为存储结构时,只存储了结点的左右孩子信息,而没有存储结点在遍历序列中的前驱和后继信息。而要想获得这样的信息有两种方法:①遍历二叉树。在遍历过程中可得到结点的前驱和后继,但这种动态访问浪费时间;②充分利用二叉链表的空链域,将遍历过程中结点的前驱和后继信息保存下来。


一、线索二叉树是什么?

在一棵有n个结点的二叉树中,共有2*n个指针域,其中有n+1个空指针域,可以利用这些空指针来指示其前驱和后继。

大量的空余指针能否利用起来?

  • 指向前驱和后继的指针称为线索,加上线索的二叉链表就称为线索链表,相应的二叉树就称为线索二叉树

  • 对二叉树以某种次序遍历使其变为线索二叉树的过程就叫做线索化

  • 在遍历过程中,访问及诶点的操作是检查此结点的左右指针域是否为空,如果为空,将它改成指向其前驱或后继结点的线索。实现过程:设指针p指向当前结点,pre指向刚访问过的结点,即p的前驱;这样便于修改pre的后继线索和p的前驱线索。


二、线索二叉树结构

1.结点结构

结点代码实现: 

type struct BiThrNode{
    ElemType data;
    struct BiThrNode *lchild,*rchild;
    int ltag,rtag;
}BiThrNode,*BiThrNode;

 说明:


三、二叉树的线索化

1、三种二叉树的线索化


四、线索二叉树中结点的前驱和后继查找

1、中序线索二叉树

(1)结点p的中序前驱结点

①若p的ltag=1,lchild指向其前驱;

②若p的ltag=0,p的前驱是以该结点为根的左子树上按中序遍历的最后一个结点。

(2)结点p的中序后继结点

①若p的rtag=1,rchild指向其后继;

②若p的rtag=0,p的后继是以该结点为根的右子树上按中序遍历的第一个结点。

2. 后序线索二叉树

(1)查找结点*p的前驱

若结点*p无左子树,则p->lchild指向其前驱

若结点*p有左子树,当其右子树为空时,其左子树的根(即p->lrchild)为其后序前驱。当其右子树非空时,其右子树的根(即p->rchild)为其后序前驱。

(2)查找结点*p的后继

若结点*p为根,则无后继;

若结点*p为其双亲的右孩子,则其后继为其双亲;

若结点*p为其双亲的左孩子,且双亲无右子女,则其后继为其双亲;

若结点*p为其双亲的左孩子,且双亲有右子女,则结点*p的后继是其双亲的右子树中按后序遍历的第一个结点。

所以,求后序线索二叉树中结点的后继要知道其双亲的信息,要使用栈,所以说后序线索二叉树是不完善的。

3.先序线索二叉树

在先序线索二叉树中查找结点的后继较容易,而查找前驱要知道其双亲的信息,要使用栈,所以说先序线索二叉树也是不完善的。

猜你喜欢

转载自blog.csdn.net/Jacky_Feng/article/details/108456056