【数据结构与算法】第十二章:线索化二叉树

简介: 在二叉树的一些应用中,常常要求在数中查找具有某种特征的结点,或者是对树中的全部结点逐一进行处理,这就提出了一个遍历二叉树的问题。本章将详细介绍二叉树的存储和遍历。

 📝3️⃣线索化二叉树

      当以二叉链表作为存储结构时,只能找到结点的左、右孩子信息,儿不能直接得到结点在任一序列中的前驱和后继信息,这种信息只有在遍历的动态过程中得到,为此引入线索二叉树来保存这些动态过程中得到的有关前驱和后继的信息。

✨相关概念

普通二叉树只能找到结点的左右孩子信息,而该结点的直接前驱和直接后继只能在遍历过程中获得。若将遍历后对应的有关前驱和后继预存起来,则从第一个结点开始就能很快顺藤摸瓜而遍历整个树。

【线索】:指结点前驱和后继的指针。

【线索二叉树】:加上线索额二叉树。

【线索化】:对二叉树以某种次序遍历使其变为线索二叉树的过程。

【线索链表】:加上线索二叉链表。

✨实现方法

通过两种保存前驱和后继的方法:

    1. 利用空链域: 二叉链表n有(n+1)个空链域。
    2. 增加两个域:fwd 和 bwd。

    在线索化二叉树时,若结点有左子树,则lchild指向其左孩子,否则,lchild指向其直接前驱(即线索)。同理,若结点有右子树,则rchild指向其右孩子,否则,rchild指向其直接后继。

    为了避免混淆,增加两个标志域。

    lchild LTag data RTag rchild

    LTag:= 0,lchild指向其左孩子, LTag:= 1,rchild指向其前驱

    同理, RTag:= 0,lchild指向其右孩子, RTag:= 1,rchild指向其后继

    ✨类型定义

    typedef struct BiThrNode
    {
        TElemType data;
        struct BiThNode *lchild,*rchild;//左右孩子指针
        int LTag, RTag;//左右标记
    }BiThrNode,*BiThrNode;

    image.gif

    ✨以结点p为根结点中序线索化

    【算法步骤】

      1. 如果p非空,左子树递归线索化。
      2. 如果p的左孩子为空,则给p加上左线索,将其LTag置为1,让p的左孩子指针指向pre(前驱);否则将p的LTag置为0。
      3. 如果pre的右孩子为空,则给pre加上右线索,将其RTag置为1,让pre的右孩子指针指向p(后继);否则将pre的RTag置为0。
      4. 将pre指向刚访问过的结点p,即pre = p。
      5. 右子树递归线索化。

      【算法描述】

      void InThreading(BiThrTree p) 
      { 
          //pre是全局变址,初始化时其右孩子指针为空,便于在树的最左点开始建线索
          if(p) 
              InThreading (p-> lchild) ;//左子树递归线索化
          if (! p-> lchild) //p的左孩子为空
              p-> LTag=1; //给p加上左线索
              p-> lchild=pre; //p的左孩子指针指向pre(前驱)
          }
          else p->LTag=O; 
          if (! pre-> rchild) //pre的右孩子为空
              pre-> RTag=1; //给pre加上右线索
              pre-> rchld=p; //pre的右孩子指针指向p(后继)
          }
          else p->RTag=O; 
          pre=p; //保持pre指向p的前驱
          InThrending (p-> rchild) ; //右子树递归线索化
      }

      image.gif

      ✨带头结点的二叉树中序线索化

      【算法描述】

      void InOrderThreading(BiThrTree &Thrt,BiThrTree T)
      {
          //中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
          Thrt = new BiThrNode;//建立头结点
          Thrt -> LTag = 0;//头结点有左孩子,若树非空,则其左孩子为树根
          Thrt -> RTag = 1;//头结点的右孩子指针为右线索
          Thrt -> rchild = Thrt;//初始化时右指针指向自己
          if(!T)
              Thrt -> lchild = Thrt;//若树为空,则左指针也指向自己
          else
          {
              Thrt -> lchild = T;//头结点的左孩子指向根
              pre = Thrt;//pre初值指向头结点
              InThreading(T);//对以T为根的二叉树进行中序线索化
              pre -> rchild = Thrt;//线索化完成后,pre为最右节点,pre的右线索指向头结点
              pre -> RTag = 1;
              Thrt -> rchild = pre;//头结点的右线索指向pre
          }
      }

      image.gif


      相关文章
      |
      22天前
      |
      算法
      【算法与数据结构】二叉树(前中后)序遍历2
      【算法与数据结构】二叉树(前中后)序遍历
      |
      8天前
      二叉树和数据结构
      二叉树和数据结构
      16 0
      |
      8天前
      |
      算法 DataX
      二叉树(中)+Leetcode每日一题——“数据结构与算法”“剑指Offer55-I. 二叉树的深度”“100.相同的树”“965.单值二叉树”
      二叉树(中)+Leetcode每日一题——“数据结构与算法”“剑指Offer55-I. 二叉树的深度”“100.相同的树”“965.单值二叉树”
      |
      19天前
      |
      算法 索引
      【算法与数据结构】深入二叉树实现超详解(全源码优化)
      【算法与数据结构】深入二叉树实现超详解(全源码优化)
      |
      19天前
      |
      存储 算法
      【算法与数据结构】深入解析二叉树(二)之堆结构实现
      【算法与数据结构】深入解析二叉树(二)之堆结构实现
      |
      29天前
      |
      存储 算法 安全
      数据结构与算法:链式二叉树
      上一篇文章我们结束了二叉树的顺序存储,本届内容我们来到二叉树的链式存储!
      数据结构与算法:链式二叉树
      |
      29天前
      |
      存储 算法 程序员
      【数据结构】【版本2.0】【树形深渊】——二叉树入侵
      【数据结构】【版本2.0】【树形深渊】——二叉树入侵
      |
      30天前
      |
      算法 C++ 开发者
      【C/C++ 数据结构 】二叉树基本性质:具有n个结点的完全二叉树的深度为[log2n]+1或者[log2(n+1)]...
      【C/C++ 数据结构 】二叉树基本性质:具有n个结点的完全二叉树的深度为[log2n]+1或者[log2(n+1)]...
      11 0
      |
      30天前
      |
      存储 算法 C语言
      【C/C++ 数据结构 树】探索C/C++中的二叉树:从理论到实践
      【C/C++ 数据结构 树】探索C/C++中的二叉树:从理论到实践
      60 0
      |
      1月前
      |
      存储 算法 Python
      数据结构与算法——二叉树介绍(附代码)
      数据结构与算法——二叉树介绍(附代码)
      22 3