美文网首页
线索化二叉树

线索化二叉树

作者: E术家 | 来源:发表于2020-04-28 11:34 被阅读0次
为什么做线索
1.二叉树如果没有左子节点或右子节点,会浪费一个节点的控件,添加线索可以额节省空间
2.正常的查询需要一个一个遍历,耗时长,添加线索后更加方便检索

代码实现

基础设置

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100 /* 存储空间初始分配量 */

/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Status;
typedef char CElemType;
/* 字符型以空格符为空 */
CElemType Nil='#';

构造

int indexs = 1;
typedef char String[24]; /*  0号单元存放串的长度 */
String str;
Status StrAssign(String T,char *chars) {
    int i;
    if(strlen(chars)>MAXSIZE)
        return ERROR;
    else
    {
        T[0]=strlen(chars);
        for(i=1;i<=T[0];i++)
            T[i]=*(chars+i-1);
        return OK;
    }
}

/* Link==0表示指向左右孩子指针, */
/* Thread==1表示指向前驱或后继的线索 */
typedef enum {Link,Thread} PointerTag;

/* 线索二叉树存储结点结构*/
typedef struct BiThrNode{
    
    //数据
    CElemType data;
    
    //左右孩子指针
    struct BiThrNode *lchild,*rchild;
    
    //左右标记
    PointerTag LTag;
    PointerTag RTag;
    
}BiThrNode,*BiThrTree;

/*
 打印
 */
Status visit(CElemType e)
{
    printf("%c ",e);
    return OK;
}

/*
 构造二叉树
 按照前序输入线索二叉树结点的值,构造二叉树T
 */

Status CreateBiThrTree(BiThrTree *T){
    
    CElemType h;
    //scanf("%c",&h);
    //获取字符
    h = str[indexs++];
    
    if (h == Nil) {
        *T = NULL;
    }else{
        *T = (BiThrTree)malloc(sizeof(BiThrNode));
        if (!*T) {
            exit(OVERFLOW);
        }
        //生成根结点(前序)
        (*T)->data = h;
        
        //递归构造左子树
        CreateBiThrTree(&(*T)->lchild);
        //存在左孩子->将标记LTag设置为Link
        if ((*T)->lchild) (*T)->LTag = Link;
        
        //递归构造右子树
        CreateBiThrTree(&(*T)->rchild);
        //存在右孩子->将标记RTag设置为Link
        if ((*T)->rchild) (*T)->RTag = Link;
    }
    
    return OK;
}

遍历

/*
 中序遍历二叉树T, 将其中序线索化,Thrt指向头结点
 */

BiThrTree pre; /* 全局变量,始终指向刚刚访问过的结点 */
/* 中序遍历进行中序线索化*/
void InThreading(BiThrTree p){
    
    /*
     InThreading(p->lchild);
     .....
     InThreading(p->rchild);
     */
    if (p) {
        //递归左子树线索化
        InThreading(p->lchild);
        //无左孩子
        if (!p->lchild) {
            //前驱线索
            p->LTag = Thread;
            //左孩子指针指向前驱
            p->lchild  = pre;
        }else
        {
            p->LTag = Link;
        }
        
        //前驱没有右孩子
        if (!pre->rchild) {
            //后继线索
            pre->RTag = Thread;
            //前驱右孩子指针指向后继(当前结点p)
            pre->rchild = p;
        }else
        {
            pre->RTag = Link;
        }
        
        //保持pre指向p的前驱
        pre = p;
        //递归右子树线索化
        InThreading(p->rchild);
    }
}

/* 中序遍历二叉树T,并将其中序线索化,Thrt指向头结点 */
Status InOrderThreading(BiThrTree *Thrt , BiThrTree T){
    
    *Thrt=(BiThrTree)malloc(sizeof(BiThrNode));
    
    if (! *Thrt) {
        exit(OVERFLOW);
    }
    
    //建立头结点;
    (*Thrt)->LTag = Link;
    (*Thrt)->RTag = Thread;
    //右指针回指向
    (*Thrt)->rchild = (*Thrt);
    
    /* 若二叉树空,则左指针回指 */
    if (!T) {
        (*Thrt)->lchild=*Thrt;
    }else{
        
        (*Thrt)->lchild=T;
        pre=(*Thrt);
        
        //中序遍历进行中序线索化
        InThreading(T);
        
        //最后一个结点rchil 孩子
        pre->rchild = *Thrt;
        //最后一个结点线索化
        pre->RTag = Thread;
        (*Thrt)->rchild = pre;
        
    }
    return OK;
}

/*中序遍历二叉线索树T*/
Status InOrderTraverse_Thr(BiThrTree T){
    BiThrTree p;
    p=T->lchild; /* p指向根结点 */
    while(p!=T)
    { /* 空树或遍历结束时,p==T */
        while(p->LTag==Link)
            p=p->lchild;
        if(!visit(p->data)) /* 访问其左子树为空的结点 */
            return ERROR;
        while(p->RTag==Thread&&p->rchild!=T)
        {
            p=p->rchild;
            visit(p->data); /* 访问后继结点 */
        }
        p=p->rchild;
    }
    
    return OK;
}

相关文章

  • 数据结构与算法分析四 树(续)

    ** 顺序存储 ** 线索化二叉树 线索化代码实现

  • 数据结构线索二叉树

    线索二叉树构成 线索化的节点 实现

  • javascript线索化二叉树

    定义二叉树创建方法 对二叉树进行中序线索化 遍历线索二叉树 测试

  • 69_二叉树的线索化实现

    关键词:二叉树的额线索化 0. 什么是线索化二叉树? 将二叉树转换为双向链表的过程(非线性==》线性) 能够反映某...

  • 数据结构题目52:二叉树的线索化

    题目:二叉树的线索化对二叉树的线索化,就是把二叉树的二叉链表存储结构中结点的所有空指针域改造成指向某结点在某种遍历...

  • 线索二叉树

    之前我们说过二叉树的顺序存储和链式存储,那么今天我们来说一下线索化二叉树是如何实现的。 线索化二叉树其实就是在二叉...

  • 线索二叉树操作

    树节点 创建中序线索二叉树 遍历中序线索二叉树 创建前序线索二叉树 遍历前序线索二叉树 参考:https://bl...

  • 详细图解二叉树线索化及其实现

    为了更好的阅读体验你可以查看我的github原文 线索二叉树节点定义 二叉树线索化的过程中,会把树中的空指针利用起...

  • 二叉树—线索二叉树

    1、线索二叉树的引入 在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或...

  • 线索二叉树

    线索二叉树产生背景 解决空间浪费 为了寻找某个结点的前驱和后继的时候更加简单快捷,利用有限的空间进行线索化的处理 ...

网友评论

      本文标题:线索化二叉树

      本文链接:https://www.haomeiwen.com/subject/vuhvwhtx.html