• 二叉树的线索化


    二叉树的线索化

    线索二叉树:

    1. 中序线索化 左中右
    2. 先序线索化 中左右
    3. 后序线索化 左右中

    用土办法找到中序前驱

    //中序遍历
    void findPre(BiTree T){
    	if(T!=NULL){
    		findPre(T->lchild); //递归遍历左子树
    		visit(T);//访问根节点
    		findPre(T->rchild);//递归遍历右子树
    	}
    }
    
    //访问结点q
    void visit(BiTNode *q){
    	if(q==p){	//当前访问结点刚好是系结点
    		final = pre;	//找到p的前驱
    	}else{
    		pre = q;	//pre指向当前访问的结点
    	}
    	
    }
    
    //辅助全局变量,用于查找结点p的前驱
    BiTNode *p; //p指向目标结点
    BiTNode * pre = NULL;//指向当前访问的结点
    BiTNod * final = NULL;//用于记录最终结点
    

    中序线索化

    左中右

    //全局变量pre,指向当前访问结点的前驱
    ThreadNode *pre=NULL;
    
    void CreateInThread(ThreadTree T){
        pre = NULL;	//pre初始值为NULL
        if(T!=NULL){	//非空的二叉树才能线索化
            InThread(T);	//中序线索化二叉树
            if(pre->rchild==NULL){
                pre->rtag=1;	//处理遍历的最后一个结点
            }
        }
    }
    
    //线索二叉树结点
    typedef struct ThreadNode{
        ElemTyoe data;
        struct ThreadNode *lchild,*rchild;
        int ltag,rtag;//左、右线索标志
    }ThreadNode,*ThtreadTree;
    
    //中序遍历二叉树,一边遍历一遍线索化
    void InThread(ThreadTree T){
    	if(T!=NULL){
    		InThread(T->lchild);
    		visit(T);
    		InThread(T->rchild);
    	}
    }
    
    void visit(ThreadNode *q){
        if(q->lchild==NULL){//左子树为空,建立前驱线索
            q->lchild=pre;
            q->ltag=1;//修改ltag,线索
        }
        if(pre!=NULL&&pre->rchild==NULL){
            pre->rchild=q;//建立前驱结点的后继线索
            pre->rtag=1;
        }
        pre=q;
    }
    

    先序线索化

    中左右

    注意:做了前驱线索,小心遍历的时候无限转圈圈。

    //全局变量pre,指向当前访问结点的前驱
    ThreadNode *pre=NULL;
    
    //先序线索化二叉树T
    void CreatePreThread(ThreadTree T){
        pre = NULL;
        if(T!=NULL){
            PreThread(T);
            if(pre->rchild == NULL){
                pre->rtag = 1;
            }
        }
    }
    
    //先序遍历二叉树,一边遍历一边线索化
    void PreThread(ThreadTree T){
        visit(T);	//先处理根节点
        if(T->ltag == 0){	//lchild不是前驱线索,提防无限转圈
            PreThread(T->lchild);
        }
        PreThread(T->rchild);
    }
    
    void visit(ThreadNode *q){
        if(q->lchild==NULL){	//左子树为空,建立前驱线索
            q->lchild = pre;
            q->ltag = 1;
        }
        if(pre!=NULL&&pre->rchild==NULL){
            pre->rchild = q;	//建立前驱结点的后继线索
            pre->rtag = 1;
        }
        pre = q;
    }
    

    后序线索化

    左右中

    //全局变量pre,指向当前访问结点的前驱
    ThreadNode *pre=NULL;
    
    //先序线索化二叉树T
    void CreatePreThread(ThreadTree T){
        pre = NULL;
        if(T!=NULL){
            PreThread(T);
            if(pre->rchild == NULL){
                pre->rtag = 1;
            }
        }
    }
    
    //后序遍历二叉树,一边遍历一边线索化
    void PostThread(ThreadTree T){
        PostThread(T->lchild);
        PostThread(T->rchild);
        visit(T);	//最后处理根节点
    }
    
    void visit(ThreadNode *q){
        if(q->lchild==NULL){	//左子树为空,建立前驱线索
            q->lchild = pre;
            q->ltag = 1;
        }
        if(pre!=NULL&&pre->rchild==NULL){
            pre->rchild = q;	//建立前驱结点的后继线索
            pre->rtag = 1;
        }
        pre = q;
    }
    

    总结

  • 相关阅读:
    小程序对于华为Oppo的canvas二维码渲染数据量大
    SonarQube代码质量管理工具的升级(sonarqube6.2 + sonar-scanner-2.8 + MySQL5.6+)
    SonarQube代码质量管理工具安装与使用(sonarqube5.1.2 + sonar-runner-dist-2.4 + MySQL5.x)
    在try-catch机制优化IO流关闭时,OutputStreamWriter 数据流被截断
    Java中日期格式化SimpleDateFormat类包含时区的处理方法
    彻底删除mysql服务(清理注册表)
    PHP7新特性的介绍
    RESTful架构详解
    php-config 介绍
    用 phpize 编译共享 PECL 扩展库
  • 原文地址:https://www.cnblogs.com/jev-0987/p/13199997.html
Copyright © 2020-2023  润新知