二叉树的线索

  关于二叉树的链表,数组等表示法,都存在一个明显更的缺点,无法直接访问其每个节点的后继和前驱。对于有一些数据的便利需求显然是无法满足的。因此就提出了二叉树的线索这一方法。其核心就是在遍历二叉树的同时能直接对节点的前驱和后继进行访问操作。

  二叉树的线索具体做法是在每一个二叉树的的节点上面添加两个额外的标签LTag,RTag。利用二叉树节点已有的左右孩子指针,在节点有孩子的情况下将Tag标签置为0(哪一侧有就将对应侧的标签置为0),原来左右孩子指针依然指向各自的孩子不变;当节点无孩子时将Tag标签置为1(哪一侧无就将哪一侧对应得标签置为1),并且将原来的孩子指针指向其前驱(LTag为1时)或后继(RTag为1时)。这样不仅能解决传统二叉树无法访问其节点前驱后继的问题还可以极大的利用二叉树节点已有的数据空间。(任何一个二叉树节点的任何一侧其Tag标签要么为0要么为1,二者只能选一个,这是上述方法可行的基本条件)

//二叉树线索的数据结构
typedef enum PointerTag{Precusor,Succeed};//Precusor==0:指针,succeed==1线索
typedef struct Node{
   char data;
   struct Node *lchild, *rchild;
   PointerTag  LTag,RTag;
}BiNode,*BiTree;

  

我们来仔细分析一下二叉树线索(以中序遍历为例)的过程:如上图由头节点开始向下按T->lchild遍历直到到达D节点然后开始输出节点D的data此时D的RTag为1(Succeed即枚举的第二个值).此时T->rchild指向的是该节点的后继即为B节点然后输出B节点的data。此时B的rtag变为0(Precursor即为枚举的第一个值)接着访问E节点此时E的RTag为1,此时T->data为该节点的后继即为A。以此方式遍历整个二叉树。

  二叉树线索的实现代码:

  1,非递归法

typedef struct BiTree p;
InOrder(BiTree T){
    p=T->lchild; //p指向二叉树根节点  while(p!=T){    while(p->lchild==Precusor) p=p->lchild;    printf("%c",p->data);    if(p->data){      while(p->RTag==Succeed&&p->rchild!=T){        p=p->rchild;        printf("%c",p->data);      }      p=p->rchild;    }  }}

   2,递归调用法

typedef struct BiTree pre;
InOrder(BiTree T,BiTree &Thrt){
    Thrt=(BiTree)malloc(sizeof(BiNode))    //Thrt为头结点
    if(Thrt){
         Thrt->LTag=Precusor;
         Thrt->RTag=secceed;
         Thrt->rchild=Thrt;
    }
    if(Thrt->lchild){
        Thrt->lchild=T;
        pre=Thrt;     InThread(T);     pre->rchild=Thrt;     pre->rTag=Succeed;     Thrt->rchild=pre;
    }   return 0;
} 

InThread(BiTree p) {  if(p){    InThread(p->lchild);    if(!p->lchild) {p->LTag=Succeed;p->lchild=pre;}    if(!pre-rchild){pre->RTag=Succeed;pre->rchild=p;}    pre=p;    InTread(p->rchild);  }}      

  以上就是关于二叉树线索的初步概括,水平有限!仅供学习参考用!

时间: 2024-08-08 03:20:10

二叉树的线索的相关文章

二叉树之线索二叉树

相对于顺序存储结构而言,利用链式存储结构的二叉树已经有了很高的存储效率,单是还是有空间上未利用到的地方,比如说叶子结点的左右孩子是空的,指向左右孩子的指针就是空闲的,没有被利用到:而且,有时候给定一个结点,我们需要查找该结点的前驱结点和后继结点,如果按照中序遍历的做法去查找的话,对于一个非叶子结点,其前驱和后继结点查找可以以下算法: 1.preNode=node.left;//前去结点就是该结点的左孩子 2.subNode=search(node.right)://后继结点是该结点的右子树的最左

二叉树的线索化算法思想详解

二叉树的线索化,这几天以来我很难掌握,今天终于想通了,哈哈,首先我们来看看二叉树线索化之后会变成什么样子,这里我们以图中的二叉树为例,图如下: 画的太糙,各位看官讲究着看吧- -.所谓二叉树的线索化,就是当一个节点的左右指针为空时,就让它的左右指针指向该节点的前驱或者后继(一般来说左指针指向前驱,右指针指向后继).这里不论指向前驱或者后继,我们都应该线索化时,至少要明确两个节点指针的值,当前节点和当前节点的前驱/后继.这也是线索化的两种思路: 保存前驱:访问当前节点时若当前节点的左指针为空,则令

二叉树及其线索化分析

1. Where did it could work? /** *    Q: Where did it could work? * *    A: Bin-tree is generally used in deal with work about search or sort. For a  balance tree, it's depth is log2(n). That's means if we want to find a  node in the tree we need *   

二叉树的层序遍历和二叉树的线索化

先根,后子树:先左子树,后右子树 二叉树的根节点 a 入队 a 的子树,根节点 b 和 c 分别入队 然后 b 的子树的根节点入队(为空) c 的子树的根节点入队 d 的子树的根节点入队(为空) e 的子树的根节点入队 f 的子树的根节点入队(为空) g的子树的根节点入队(为空)结束层序遍历,整个过程就是一层层的遍历,依靠一个队列来存放临时查找的结点. 二叉树线索化 问题的提出:当以二叉链表作为存储结构时,只能找到结点的左右孩子的信息,而不能直接找到结点的任一序列的前驱与后继信息,这种信息只有在

6.3线索二叉树(二叉树的线索化)

6.3线索二叉树(二叉树的线索化) 问题引入:以二叉链表作为存储结构时,只能得到结点的左.右孩子的信息,不能得到直接前驱.后继的信息. 问题解决:将二叉树线索化. 实现原理:n个结点的二叉树具有n+1个空指针域,利用这些空指针域存储结点的前驱.后继信息. 实质:线索化的实质是将二叉链表中的空指针改为指向前驱.后继的线索. (1)二叉树的存储表示 enum {link,thread};//link=0; thread=1; typedef struct bintree { char data; s

树——二叉树的线索化

1,什么是线索化二叉树? 1,将二叉树转换为双向链表的过程(非线性 ==> 线性): 1,实际工程开发中,很大一部分情况下,二叉树一旦建立之后,就不会轻易改动,一般的用于遍历,并且这种操作一般执行很多: 2,先中后序遍历都是递归完成的,实际工程开发中,对一棵已经建立的二叉树反复执行先序遍历,效率低,所以不推荐反复的递归的遍历: 3,直接将遍历后的结果保存下来,下一次遍历直接用这个结果就可以: 4,工程开发中还有一种常见情况,就是要反复的知道某个结点在中序遍历下,前驱结点是谁.后继结点是谁,需要这

二叉树的线索化

---恢复内容开始--- 遍历二叉树是以一定规则将二叉树中结点排列成一个线性序列即是对一个非线性结构进行线性化操作,使除第一个和最后一个节点外,每一个节点有且只有一个直接前驱,直接后继 二叉树作为存储结构只能找到节点的左孩子右孩子信息,而不能直接得到结点在任一序列中的前驱和后继,这种信息只有在遍历的动态过程中可以看到. 二叉树线索化可以利用二叉树中指向左右子树的空指针来存放节点的前驱和后继信息可以使用以下结点结构: enum pointertag{ Link, Thread };template

数据结构--二叉树的线索化

线索二叉树它解决了无法直接找到该结点在某种遍历序列中的前趋和后继结点的问题,出现了二叉链表找左.右孩子困难的问题,线索二叉树又分为前序线索化,中序线索化和后序线索化,分别用不同的逻辑去实现. 线索二叉树的实现思想:借用一个枚举类型tag其中包含两个状态Link(代表有数据),thread(代表下一个节点为空)在一个节点的左节点或者右节点为空的情况下,将它的left或right设为thread,则它的左或右访问的是改遍历模式下访问到的下一个节点数据,这样就完成了跳到另一颗子树的过程,减少了递归的次

第六十九课 二叉树的线索化实现

在工程中,很多时候二叉树一旦建立就不会轻易改动,这样的二叉树就用于遍历,我们讲了先序遍历.中序遍历.后续遍历三种方式,都是递归完成的,在工程中,如果对一棵二叉树反复的执行遍历,效率很低,递归的效率是比较低的. 改进的做法就是将遍历的结果保存下来,下一次遍历时直接用这个结果. 在工程中另一种需求就是,在中序遍历下,需要知道某一个节点的前驱是谁,后继是谁,需要这三个节点来判断是否执行后续的操作.这个时候又需要遍历了.每次都递归的进行遍历,效率太低了. 为了效率,我们使用线索化二叉树的方法,将二叉树转