java 线索二叉树的构建

public class test {
    public static void main(String[] args) {
        Node root = new Node(1);
        Node node2 = new Node(2);
        Node node3 = new Node(3);
        Node node4 = new Node(4);
        Node node5 = new Node(5);
        Node node6 = new Node(6);
        Tree tree = new Tree();
        tree.root = root;
        root.setLeft(node2);
        root.setRight(node3);
        node2.setLeft(node4);
        node2.setRight(node5);
        node3.setLeft(node6);
        tree.indixThread(root);
        tree.throughIndixThread(root);
    }
}

class Tree{
    // 自己的线索二叉树
    public Node root;
    public Node pre = null;
    public Tree(){

    }
    // 可以进行中序线索化和不使用递归的中序遍历
    public void indixThread(Node node){
        if(node==null){
            return ;
            // 退出
        }
        // 左中右
        indixThread(node.getLeft());
        // 来中 前 后
        if(node.getLeft()==null){
            node.setLeft(pre);
            node.setLefttype(1);
        }
        if(pre!=null&&pre.getRight()==null){
            pre.setRight(node);
            pre.setRighttype(1);
        }
        // 更新
        pre = node;
        // 后
        indixThread(node.getRight());
    }
    // 进行线索二叉树的中序遍历
    public void throughIndixThread(Node node){
        while(node!=null){
            while(node.getLefttype()==0){
                node = node.getLeft();
            }
            System.out.println(node);
            while(node.getRighttype()==1){
                node = node.getRight();
                System.out.println(node);

            }
            node = node.getRight();
        }
    }
}
class Node{
    // 节点类 需要val left right leftType rightType
    int val;
    Node left;
    Node right;

    @Override
    public String toString() {
        return "Node{" +
                "val=" + val +
                '}';
    }

    int lefttype;
    int righttype;

    public Node(int val) {
        this.val = val;
    }

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }

    public int getLefttype() {
        return lefttype;
    }

    public void setLefttype(int lefttype) {
        this.lefttype = lefttype;
    }

    public int getRighttype() {
        return righttype;
    }

    public void setRighttype(int righttype) {
        this.righttype = righttype;
    }
}

线索二叉树是用二叉树中多余的 n+1 个指针来构建当前节点的前序和后继的过程 下面我来解释一下如何从普通的二叉树构建成线索二叉树以及不使用递归来进行线索二叉树的中序遍历

public void indixThread(Node node){
        if(node==null){
            return ;
            // 退出
        }
        // 左中右
        indixThread(node.getLeft());
        // 来中 前 后
        if(node.getLeft()==null){
            node.setLeft(pre);
            node.setLefttype(1);
        }
        if(pre!=null&&pre.getRight()==null){
            pre.setRight(node);
            pre.setRighttype(1);
        }
        // 更新
        pre = node;
        // 后
        indixThread(node.getRight());
    }

我们的tree类定义了一个pre 这个就是当前节点按照遍历的顺序的前一个节点 当我们遍历到第一个元素的时候 它是没有前一个节点的 因为它是遍历的第一个 所以它的前一个节点就是null 

我们初始化pre的时候就为null

我们有了node 当前节点和 pre上一个节点 就可以判断能不能搭桥

// 由于是中序遍历 我们需要先左 再中右

indixThread(node.left);

if(node.left==null) 当前节点没有左指针 就利用这个节点指向前一个节点

node.setLeft(pre)

在判断前一个节点

if(pre!=null&&pre.right==null){

        pre.setRight(node)
}

这时 我们正式完成了指针的利用 需要进入到下一个节点 所以就需要更新pre的值

pre = node;

最后 进入到右子树进行遍历

indixThread(node.right);

 

public void throughIndixThread(Node node){
        while(node!=null){
            while(node.getLefttype()==0){
                node = node.getLeft();
            }
            System.out.println(node);
            while(node.getRighttype()==1){
                node = node.getRight();
                System.out.println(node);

            }
            node = node.getRight();
        }
    }

进行线索二叉树的无递归遍历

我们首先要找到第一个元素 由于是中序遍历 所以它的特点是在左子树第一个leftType为1的地方

因为我们设置它的前序是null 

使用while来寻找 直到找到 打印出这个节点

当right的type为1时 right就是下一个节点 我们可以直接打印

while(node.getRightType()==1){

node = node.right();

sout(node);

}        

当出循环的时候 就来到了中间的节点 因为它本来就有右子树 所以righttype为0

我们需要进入右子树再进行中序遍历的逻辑 所以

node = node.getRight(); 此时停手 进入下一轮循环

相当于进入右子树后在根据中序遍历的逻辑进行判断.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值