利用栈实现线索化二叉树_数据结构系列二叉树遍历和线索化

由遍历序列确定二叉树

    从二叉树的遍历可知,任何一棵二叉树的前序遍历和中序遍历都是唯一的,那么给定结点的前序序列和中序序列能否确定一棵二叉树?

    二叉树的前序序列中,第一个结点必定是根D;根节点D可将中序序列分成两部分:D之前是左子树的中序序列,D之后是右子树的中序序列,再根据左子树的中序序列,又可将前序序列除根以外分成左子树的前序序列和右子树的前序序列,以此类推,便可递归得到整棵二叉树。

    结论:给定一颗二叉树的前序序列和中序序列,可以唯一的确定一棵二叉树。

二叉树的线索化

    线索化是在遍历的过程中修改空指针域的过程。

    对二叉树按照不同的遍历次序进行线索化,可以得到先序,中序,后序线索二叉树。

示例

中序线索化算法思路:按照中序遍历的规则,

当访问的节点root        root的前驱结点pre

root无左--->prey为root的前驱

root为pre的后继

b233d39eef7de12a9474df607f2753a7.png

void Inthread(BiTree root)// 对root所指的二叉树进行中序线索化,其中pre始终指向刚访问过的结点,其初值为NULL{
      if(roo!=NULL)  Inthread(root->LChild);  // 线索化左子树  if(root->LChild==NULL)  {
        root->Ltag=1;LChild=pre;    // 置前驱线索    if(pre!=MULL && pre->RChild==NULL)    // 置后继线索    pre->RChild=root;pre->Rtag=1;    pre=root;    Inthread(root->RChild);    // 线索化右子树  }}

线索化之后如何找前驱后继,是线索化的重要作用

1)找结点的中序前驱结点

假设中序遍历序列如下:1c0e9b666e2dff7f6d1140f8487e618b.png

问题:P的中序前驱x节点在树中什么位置?

答:x结点应该在p的左子树的“最右下端”。

左子树最后一个被访问的点

15ac75d2b978b6b8a5c2e4ed03d2b3d2.png

void InPre(BiTNode*p,BiTNode*pre)// 在中序线索二叉树中查找p的中序前驱,并用pre指针返回结果{
      if(p->Ltag==1)  pre=p->LChild;  // 直接利用线索  else  {
        // 在p的左子树中查找“最右下端”结点    for(q=p->LChild;q=Rtag=0;q=q->RChild);    pre=q;  }}

2)在中序线索数中找结点后继--没有右孩子直接就是后继指针,有右孩子为右子树第一个访问节点

假设中序遍历序列如下

01bee28d367dcdb33fdbadec23a9b088.png

问题:p的中序后继结点x在树中的什么位置?

答:x节点应该在p的右子树的最左下端。

170cdbe0645009fc1d01c89b4b151d65.png

void InSucc(BiTNode*p,BiTNode*succ)// 在中序线索二叉树中查找p的后继结点,并用succ指针返回结
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值