zoukankan      html  css  js  c++  java
  • 线索二叉树

    一、线索二叉树的原理

        通过考察各种二叉链表,不管儿叉树的形态如何,空链域的个数总是多过非空链域的个数。

         n各结点的二叉链表共有2n个链域,非空链域为n-1个,但其中的空链域却有n+1个。如下图所示。

      (除根结点以外,所有结点都有一共指向它的结点,所有非空链域为n-1,空链域为n+1)

      因此,提出了一种方法,利用原来的空链域存放指针,指向树中其他结点。这种指针称为线索。

        记ptr指向二叉链表中的一个结点,以下是建立线索的规则:

        (1)如果ptr->lchild为空,则存放指向中序遍历序列中该结点的前驱结点。这个结点称为ptr的中序前驱;

        (2)如果ptr->rchild为空,则存放指向中序遍历序列中该结点的后继结点。这个结点称为ptr的中序后继;

      显然,在决定lchild是指向左孩子还是前驱,rchild是指向右孩子还是后继,需要一个区分标志的。因此,我们在每个结点再增设两个标志域ltag和rtag,注意ltag和rtag只是区分0或1数字的布尔型变量,其占用内存空间要小于像lchild和rchild的指针变量。结点结构如下所示。

        其中:

        (1)ltag=0    时指向该结点的左孩子,为1时指向该结点的前驱

        (2)rtag=0   时指向该结点的右孩子,为1时指向该结点的后继

        (3)因此对于上图的二叉链表图可以修改为下图下的样子。

      

    二、线索二叉树结构实现

      存储结构

    typedef char DataType;
    typedef enum{Link, Thread}PointerTag;    //Link = 0表示指向左右孩子指针;Thread = 1表示指向前驱或后继的线索
    struct BitNode{
        DataType data;
        BitNode *lchild, *rchild;
        PointerTag ltag;
        PointerTag rtag;   
    };
    typedef BitNode* BitTree;
     中序遍历线索化
    BitTree pre;
    void InThreading(BitTree p){
        if(p){
            InThreading(p->lchild);//递归左子树线索化
            if (!p->lchild)//没有左孩子
            {
               p->ltag= Thread;//前驱线索
               p->lchild=pre;//左孩子指向前驱
            }
            if (!p->rchild)//没有右孩子
            {
               pre->rtag= Thread;//后继线索
               pre->rchild=p;//前驱右孩子指向后继
            }
            pre = p;
            InThreading(p->rchild);
        }
    }
    中序遍历二叉线索树表示二叉树t
    int InOrderThraverse_Thr(BiTree t)
    {
        BiTree p;
        p=t->lchild;                               //p指向根结点
        while(p!= t)                               //空树或遍历结束时p == t
        {
            while(p->ltag == Link)       //当ltag = 0时循环到中序序列的第一个结点
            {
                p = p->lchild;
            }
            cout<<p->data<<" ";     //显示结点数据,可以更改为其他对结点的操作
            while(p->rtag == Thread && p->rchild != t)
            {
                p = p->rchild;
                cout<<p->data<<" "; 
            }
            p = p->rchild;                         //p进入其右子树
        }
     
        return 0;
    }

     

    因上求缘,果上努力~~~~ 作者:每天卷学习,转载请注明原文链接:https://www.cnblogs.com/BlairGrowing/p/13039631.html

  • 相关阅读:
    前端+php实现概率抽奖
    rem.js的用法及在浏览器端的适配
    python 使用记录及问题
    python 工具链 虚拟环境和包管理工具 pipenv
    python 工具链 多版本管理工具 pyenv
    python 工具链 包管理工具 pip
    ansible 使用记录
    mongodb connection refused because too many open connections: 819
    wordpress 常用操作
    服务器硬件测试
  • 原文地址:https://www.cnblogs.com/BlairGrowing/p/13039631.html
Copyright © 2011-2022 走看看