1. 程式人生 > 其它 >java實現中序線索化二叉樹遍歷

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