美文网首页
数据结构与算法学习 (11)线索二叉树

数据结构与算法学习 (11)线索二叉树

作者: 暱稱已被使用 | 来源:发表于2020-05-20 21:12 被阅读0次

对于n个结点的二叉树,在二叉链存储结构中有n+1个空链域,利用这些空链域存放在某种遍历次序下该结点的前驱结点和后继结点的指针,这些指针称为线索,加上线索的二叉树称为线索二叉树。

本质:二叉树的遍历本质上是将一个复杂的[非线性结构]转换为[线性结构],使每个结点都有了唯一前驱和后继(第一个结点无前驱,最后一个结点无后继)。对于二叉树的一个结点,查找其左右子女是方便的,其前驱后继只有在遍历中得到。为了容易找到前驱和后继,有两种方法。一是在结点结构中增加向前和向后的指针,这种方法增加了存储开销,不可取;二是利用二叉树的空链指针。
优缺点:
优势 :1、利用线索二叉树进行中序遍历时,不必采用堆栈处理,速度较一般二叉树的遍历速度快,且节约存储空间。
2、任意一个结点都能直接找到它的前驱和后继结点。
不足 :1、结点的插入和删除麻烦,且速度也较慢。
2、线索子树不能共用

代码实现:

1.线索二叉树存储结点结构

typedef struct BiThrNode{
    
    //数据
    CElemType data;
    
    //左右孩子指针
    struct BiThrNode *lchild,*rchild;
    
    //左右标记
    PointerTag LTag;
    PointerTag RTag;
    
}BiThrNode,*BiThrTree;
2.按照前序输入线索二叉树结点的值,构造二叉树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;
}
3.中序遍历进行中序线索化

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);
    }
}
4.中序遍历二叉树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;
}
5.中序遍历二叉线索树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;
}


相关文章

网友评论

      本文标题:数据结构与算法学习 (11)线索二叉树

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