java实现线索化二叉树的前序,中序,后续的遍历(完整代码)

  

java实现线索化二叉树的前序,中序,后续的遍历

  

比如创建一个二叉树

  
 <代码> 1/\
  3个6/\/8 10 14  
  
      <李>   

    <强>线索化二叉树几个概念:

      
        <李> n个节点的二叉链表中含有n + 1
      【公式2 n - (n - 1)=n + 1】个空指针域。利用二叉链表中的空指针域,存放指向该节点在某种遍历次序下的前驱和后继节点的指针(这种附加指针成为线索)。
      如下面的就是6 + 1=7个空指针域(8、10、14各有连个指针没有指向6有一个)   <李>加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树。分为前序线索二叉树,中序线索二叉树,后序线索二叉树李   <李>一个节点的前一个节点,称为前驱节点李   <李>一个节点的后一个节点,称为后继节点李   <李>线索化后的二叉树,节点可能指向的是前驱或者后继节点,也有可能指向的是本身的二叉树的节点李   
      李   <李> <>强前序,中序,后序线索化和遍历   
  
 <代码>//创建树的节点/* *
  * <节点定义>
  *
  * @author尼克
  * @create 2019/9/17
  * @since 1.0.0
  */@ data
  公开课HeroNode {
  私人int没有;
  私人字符串名称;/* *
  *//默认null
  */私人HeroNode离开;/* *
  *//默认null
  */私人HeroNode正确;/* *
  *//父节点的指针(为了后序线索化使用)
  */私人HeroNode父母;/* *
  *//说明
  *//1。如果leftType==0表示指向的是左子树,如果1则表示指向前驱结点
  *//2。如果rightType==0表示指向是右子树,如果1表示指向后继结点
  */私人int leftType;
  私人int rightType;
  
  公共HeroNode (int不,字符串名称){
  这一点。没有=;
  this.name=名称;
  }
  
  @Override
  公共字符串toString () {
  返回“HeroNode(没有=" +不+”,name=" +名字+ "]”;
  }
  
  }
   之前
  
 <代码>/* *
  * <线索化二叉树>
  * 1
  */\
  6 * 3
  */\/* 8 10 14
  *
  * @author尼克
  * @create 2019/9/17
  * @since 1.0.0
  */公开课ThreadedBinaryTree {
  私人HeroNode根;/* *
  *为了实现线索化,需要创建要给指向当前结点的前驱结点的指针
  *在递归进行线索化时,总以前是保留前一个结点
  */私人HeroNode pre=零;
  
  公共空间setRoot (HeroNode根){
  这一点。根=根;
  }/* *
  *重载一把threadedNodes方法
  */公共空间threadedNodes () {
  this.threadedNodes(根);
  }/* *
  *重载一把threadedNodesPre方法
  */公共空间threadedNodesPre () {
  this.threadedNodesPre(根);
  }/* *
  *重载一把threadedNodesAfter方法
  */公共空间threadedNodesAfter () {
  this.threadedNodesAfter(根);
  }/* * * * * * * * * * * * * * * * * * * * * * *遍历线索化二叉树开始* * * * * * * * * * * * * * * * * * * * * *//* *
  *中序遍历线索化二叉树的方法
  * & lt; p>
  */公共空间threadedList () {//定义一个变量,存储当前遍历的结点,从根开始
  HeroNode节点=根;
  而(节点!=null) {//循环的找到leftType==1的结点,第一个找到就结是8点//后面随着遍历而变化,因为当leftType==1时,说明该结点是按照线索化//处理后的有效结点
  而(node.getLeftType ()==0) {
  节点=node.getLeft ();
  }//打印当前这个结点
  System.out.println(节点);//如果当前结点的右指针指向的是后继结点,就一直输出
  而(node.getRightType ()==1) {//获取到当前结点的后继结点
  节点=node.getRight ();
  System.out.println(节点);
  }//替换这个遍历的结点
  节点=node.getRight ();
  
  }
  }/* *
  *前序线索化二叉树遍历方法
  * 1
  */\
  6 * 3
  */\/* 8 10 14
  * & lt; p>
  * {1、3、8、10 6 14}
  */公共空间threadedListPre () {//定义一个变量,存储当前遍历的结点,从根开始
  HeroNode节点=根;
  而(节点!=null) {
  而(node.getLeftType ()==0) {//如果是叶子节点,非前驱节点,打印当前这个结点
  system . out。打印(节点+”、“);
  节点=node.getLeft ();
  }
  system . out。打印(节点+”、“);//替换这个遍历的结点
  节点=node.getRight ();
  }
  }/* *
  *后序线索化二叉树遍历方法
  * & lt; p>
  *注意后序有点复杂,需要建立二叉树的时候,将节点的父母进行赋值,否则不能遍历成功
  * 1
  */\
  6 * 3
  */\/* 8 10 14
  * & lt; p>
  * {8 10 3 1 14 6}
  * 1。如果leftType==0表示指向的是左子树,如果1则表示指向前驱结点
  * 2。如果rightType==0表示指向是右子树,如果1表示指向后继结点
  */公共空间threadedListAfter () {//1,找后序遍历方式开始的节点
  HeroNode节点=根;
  而(节点!=零,,node.getLeftType ()==0) {
  节点=node.getLeft ();
  }
  而(节点!=null) {//右节点是线索
  如果(node.getRightType ()==1) {
  system . out。打印(节点+”、“);
  pre=节点;
  节点=node.getRight ();
  其他}{//如果上个处理的节点是当前节点的右节点
  如果(node.getRight ()==pre) {
  system . out。打印(节点+”、“);
  如果(节点==root) {
  返回;
  }
  pre=节点;
  节点=node.getParent ();
  其他}{//如果从左节点的进入则找到有子树的最左节点
  节点=node.getRight ();
  而(节点!=零,,node.getLeftType ()==0) {
  节点=node.getLeft ();
  }
  }
  }
  }
  
  }/* * * * * * * * * * * * * * * * * * * * * * *遍历线索化二叉树结束* * * * * * * * * * * * * * * * * * * * * *//* * * * * * * * * * * * * * * *线索化二叉树开始* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//* *
  *中序线索化
  *得到的数组{1 8、3、10日,14日6}
  * 1
  */\
  6 * 3
  */\/* 8 10 14
  *
  * @param节点就是当前需要线索化的结点
  */公共空间threadedNodes (HeroNode节点){//如果节点==null,不能线索化
  如果(节点==null) {
  返回;
  }//(一)先线索化左子树
  threadedNodes (node.getLeft ());//(二)线索化当前结点(有难度)//处理当前结点的前驱结点//以8结点来理解//8结点的。左=null, 8结点的。leftType=1
  如果(null==node.getLeft ()) {//让当前结点的左指针指向前驱结点
  node.setLeft(前);//修改当前结点的左指针的类型,指向前驱结点
  node.setLeftType (1);
  }//处理后继结点,是下一次进行处理,有点不好理解
  如果(pre !=零,,pre.getRight ()==null) {//让前驱结点的右指针指向当前结点
  pre.setRight(节点);//修改前驱结点的右指针类型
  pre.setRightType (1);
  }//! ! !每处理一个结点后,让当前结点是下一个结点的前驱结点
  pre=节点;//(三)在线索化右子树
  threadedNodes (node.getRight ());
  }/* *
  *前序线索化
  *变成数组后{1、3、8、10 6 14}
  * 1
  */\
  6 * 3
  */\/* 8 10 14
  *
  * @param节点就是当前需要线索化的结点
  */公共空间threadedNodesPre (HeroNode节点){//如果节点==null,不能线索化
  如果(节点==null) {
  返回;
  }//左指针为空,将左指针指向前驱节点//8结点的。左=上一个节点8结点的。leftType=1
  如果(node.getLeft ()==null) {//让当前结点的左指针指向前驱结点
  node.setLeft(前);//修改当前结点的左指针的类型,指向前驱结点
  node.setLeftType (1);
  }//处理后继结点,是下一次进行处理,有点不好理解
  如果(pre !=零,,pre.getRight ()==null) {//让前驱结点的右指针指向当前结点
  pre.setRight(节点);//修改前驱结点的右指针类型
  pre.setRightType (1);
  }//! ! !每处理一个结点后,让当前结点是下一个结点的前驱结点
  pre=节点;//(一)先线索化左子树
  如果(node.getLeftType () !=1) {
  threadedNodesPre (node.getLeft ());
  }//(三)再线索化右子树
  如果(node.getRightType () !=1) {
  threadedNodesPre (node.getRight ());
  }
  
  }/* *
  *后序线索化
  *变成数组后{1 8 10 3日,14日6}
  *
  * @param节点
  */公共空间threadedNodesAfter (HeroNode节点){//如果节点==null,不能线索化
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null

java实现线索化二叉树的前序,中序,后续的遍历(完整代码)