线索二叉树

在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化。
比较常见的是中序,这里我讲的是中序线索化。

线索化

现将某结点的空指针域指向该结点的前驱后继,定义规则如下:

若结点的左子树为空,则该结点的左孩子指针指向其前驱结点。
若结点的右子树为空,则该结点的右孩子指针指向其后继结点。

这种指向前驱和后继的指针称为线索。将一棵普通二叉树以某种次序遍历,并添加线索的过程称为线索化。

构建线索二叉树

这里要注意的是

若结点的右子树为空,则该结点的右孩子指针指向其后继结点。

这里如果前驱的节点的右孩子为空,那么前驱的节点的后继就是当前节点

    public void buildDfsMiddle(Node node){
        if (node == null) {
            return;
        }
        // 构建左孩子
        buildDfsMiddle(node.left);
        // 如果左孩子为空,前驱
        if(node.left==null){
            node.lflag = 1;
            node.left = pre;
        }
        // 如果前驱的节点的右孩子为空,那么前驱的节点的后继就是当前节点
        if(pre!=null&&pre.right==null){
            pre.rflag = 1;
            pre.right = node;
        }
        pre = node;
        // 构建右孩子
        buildDfsMiddle(node.right);

    }

遍历

中序遍历

中序遍历要注意的是是我们从左子树的最左面开始遍历
然后如果我们有后继,我们就直接遍历后继
如果是右子树,那么我们还要遍历到右子树的最左面的节点

    // 线索树中序遍历
    public void dfsClueMiddle(Node node){
        // 首先中序遍历的第一个遍历是最左面的那个
        while (node!=null&&node.lflag!=1){
            node = node.left;
        }
        while (node!=null){
            System.out.println(node.val);
            if(node.rflag==1){
                node = node.right;
            }else {
                node = node.right;
                while (node!=null&&node.lflag!=1){
                    node = node.left;
                }
            }
        }
    }

后序遍历

后序遍历我们要先看还有没有左子树 如果没有左子树那么我们就看有没有右子树
如果都没有,我们就需要看当前的节点的后继的右孩子(这里要注意的是该节点的后继还有后继)

    public void dfsClueFront(Node node){
       while (node!=null){
           System.out.println(node.val);
           if(node.lflag!=1){
               node = node.left;
               continue;
           }
           if(node.rflag!=1){
               node = node.right;
               continue;
           }
           while (node.rflag==1){
               node = node.right;
           }
           node = node.right;
       }
    }
posted @ 2021-12-24 19:20  度一川  阅读(149)  评论(0)    收藏  举报