java实现中序线索化二叉树遍历

java实现中序线索化二叉树遍历

节点类

/**
 * 节点类
 */
class Node {
    private int id;
    private Node left;
    private Node right;

    /**
     * 规定:
     * 1.如果leftType==0表示指向是左子树,如果等于1表示指向前驱节点
     * 2.如果rightType==0表示指向是右子树,如果等于1表示指向后继节点
     */
    private int leftType;
    private int rightType;


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

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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;
    }
}

二叉树类

/**
 * 线索化二叉树
 */
class ThreadBinaryTree {
    private Node root;

    // 为了实现线索化,需要当前节点的前驱节点
    private Node pre = null;

    public void infixOrder() {
        Node temp = root;
        while (temp != null) {
            // 循环到找到leftType==1的节点
            while (temp.getLeftType() == 0) {
                // 移动temp
                temp = temp.getLeft();
            }
            System.out.println(temp);

            // 如果右指针指向的是后继节点,就一直输出
            while (temp.getRightType() == 1) {
                temp = temp.getRight();
                System.out.println(temp);
            }
            // 右移
            temp = temp.getRight();
        }
    }

    /**
     * 重载
     */
    public void threadedNodes() {
        this.threadedNodes(root);
    }

    /**
     * 中序线索化二叉树
     *
     * @param node 当前需要线索化的节点
     */
    public void threadedNodes(Node node) {
        // 无法线索化
        if (node == null) {
            return;
        }
        // 先线索化左子树
        threadedNodes(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
        pre = node;

        // 线索化右子树
        threadedNodes(node.getRight());

    }


    public void setRoot(Node root) {
        this.root = root;
    }
}

测试类

/**
 * 线索化二叉树
 */
public class ThreadedBinaryTree {
    public static void main(String[] args) {
        ThreadBinaryTree threadBinaryTree = new ThreadBinaryTree();

        Node root = new Node(000);

        Node node01 = new Node(001);
        Node node02 = new Node(002);
        Node node03 = new Node(003);
        Node node04 = new Node(004);
        Node node05 = new Node(005);

        // 手动创建二叉树
        threadBinaryTree.setRoot(root);
        root.setLeft(node01);
        root.setRight(node02);
        node01.setLeft(node03);
        node01.setRight(node04);
        node02.setLeft(node05);

        threadBinaryTree.threadedNodes();

        // 使用线索化方式遍历
        threadBinaryTree.infixOrder();
    }
}
posted @ 2022-04-18 17:21  CoderCatIce  阅读(42)  评论(0编辑  收藏  举报