Pre-order, middle-order, and post-order cued binary tree

Why do we need to cue the binary tree

Let's look at a question first

Construct the sequence {1, 3, 6, 8, 10, 14} into a binary tree. n+1=7

problem analysis:

1. When we traverse the above binary tree in order, the number sequence is {8, 3, 10, 1, 6, 14}

2. However, the left and right pointers of nodes 6, 8, 10, and 14 are not fully utilized.

3. What if we want to make full use of the left and right pointers of each node so that each node can point to its own front and back nodes?

4. Solution-clue binary tree

Basic introduction to threaded binary tree

1. A binary linked list of n nodes contains n+1 [formula 2n-(n-1)=n+1] null pointer fields. Use the null pointer field in the binary linked list to store pointers to the predecessor and successor nodes of the node in a certain traversal order (this kind of additional pointers are called "clues")

2. This binary linked list with clues is called a thread linked list, and the corresponding binary tree is called a threaded binary tree. According to the nature of the clues, the clue binary tree can be divided into three types: preorder clue binary tree, middle order clue binary tree and postorder clue binary tree.

3. The previous node of a node is called the predecessor node and the next node of a node is called the successor node.

Create node

class HeroNode {
    private int no;
    private String name;
    private HeroNode left;
    private HeroNode right;
    private HeroNode parent;
    //true 表示是线索化节点
    //false 表示不是线索化节点
    private boolean ThreadedLeft = false;
    private boolean ThreadedRight = false;

    public HeroNode(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public HeroNode getLeft() {
        return left;
    }

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

    public HeroNode getRight() {
        return right;
    }

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

    public HeroNode getParent() {
        return parent;
    }

    public void setParent(HeroNode parent) {
        this.parent = parent;
    }

    public boolean isThreadedLeft() {
        return ThreadedLeft;
    }

    public void setThreadedLeft(boolean threadedLeft) {
        ThreadedLeft = threadedLeft;
    }

    public boolean isThreadedRight() {
        return ThreadedRight;
    }

    public void setThreadedRight(boolean threadedRight) {
        ThreadedRight = threadedRight;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

In-order threaded binary tree

Application case description: Take the following binary tree into an in-order clue binary tree. The sequence of middle order traversal is {8, 3, 10, 1, 14, 6}

Explanation: When the binary tree is threaded, the left and right attributes of the Node node are as follows:

1. Left refers to the left subtree, or the predecessor node that it points to. For example, ① the left subtree pointed to by the node left, and the left of the ⑩ node points to the predecessor node.

2. Right points to the right subtree, or it may point to the successor node. For example, ① The node right points to the right subtree, and the right of the ⑩ node points to the successor node.

The process of in-order threading

1. In the order of the middle order traversal, the first node to be traversed is 8, and the left pointer of the 8 node is null, so let the left pointer of the 8 node point to its predecessor node, which is null

pre and node move backward

2. Continue to traverse to 3 nodes in the middle order, and its left pointer is not null

pre is 8 nodes, and its right pointer is empty, so let his right pointer point to its successor node, which is 3.

pre and node move backward

3. Continue to traverse to 10 nodes, its left pointer is empty, so it points to its predecessor node

pre is 3 nodes and its right pointer is not empty

pre and node move backward

4. Continue to traverse to node 1, and its left pointer is not empty

The pre node is 10 nodes, and its right pointer is empty, so it points to the successor node 1.

pre and node move backward

5. Continue to traverse to node 14, because its left pointer is not empty, so it points to its predecessor node 1

The pre node is 1 node, and its right pointer is not empty

pre and node move backward

6. Continue to traverse to 6 nodes, and its left pointer is empty

The pre node is 14 nodes, because its right pointer is empty, so it points to its successor node 6

pre and node move backward

The above is a process of in-order threading nodes, please see the code implementation below

private void infixThreadedNode(HeroNode node) {
        if (node == null) {
            return;
        }
        //线索化左节点
        infixThreadedNode(node.getLeft());
        //线索化当前节点
        if (node.getLeft() == null) {
            node.setLeft(pre);
            node.setThreadedLeft(true);
        }
        if (pre != null && pre.getRight() == null) {
            pre.setRight(node);
            pre.setThreadedRight(true);
        }
        pre = node;
        //线索化右节点
        infixThreadedNode(node.getRight());
    }

In-order threaded traversal

public void infixThreadedList() {
        HeroNode node = root;
        while (node != null) {
            while (!node.isThreadedLeft()) {
                node = node.getLeft();
            }
            System.out.println(node);
            while (node.isThreadedRight()) {
                node = node.getRight();
                System.out.println(node);
            }
            node = node.getRight();
        }
    }

Preorder threaded binary tree

Code

 private void preThreadedNode(HeroNode node) {
        //线索化当前节点
        if (node == null)
            return;
        if (node.getLeft() == null) {
            node.setLeft(pre);
            node.setThreadedLeft(true);
        }
        if (pre != null && pre.getRight() == null) {
            pre.setRight(node);
            pre.setThreadedRight(true);
        }
        pre = node;
        //线索化左节点
        if (!node.isThreadedLeft()) {
            preThreadedNode(node.getLeft());
        }
        //线索化右节点
        if (!node.isThreadedRight()) {
            preThreadedNode(node.getRight());
        }
    }

Pre-threaded traversal

public void preThreadedList() {
        HeroNode node = root;
        while (node != null) {
            if (!node.isThreadedLeft()) {
                System.out.println(node);
                node = node.getLeft();
            }
            System.out.println(node);
            node = node.getRight();
        }
    }

Post-cline binary tree

Code

private void postThreadedNode(HeroNode node) {
        if (node == null)
            return;
        postThreadedNode(node.getLeft());
        postThreadedNode(node.getRight());
        if (node.getLeft() == null) {
            node.setLeft(pre);
            node.setThreadedLeft(true);
        }
        if (pre != null && pre.getRight() == null) {
            pre.setRight(node);
            pre.setThreadedRight(true);
        }
        pre = node;
    }

Post-cline traversal

public void postThreadedList() {
        HeroNode node = root;
        while (node != null && !node.isThreadedLeft()) {
            node = node.getLeft();
        }
        pre = null;
        while (node != null) {
            if (node.isThreadedRight()) {
                System.out.println(node);
                pre = node;
                node = node.getRight();
            } else {
                if (node.getRight() == pre) {
                    System.out.println(node);
                    if (node == root)
                        return;
                    pre = node;
                    node = node.getParent();
                } else {
                    node = node.getRight();
                    while (node != null && !node.isThreadedLeft()) {
                        node = node.getLeft();
                    }
                }
            }
        }
    }

 

Guess you like

Origin blog.csdn.net/qq_45796208/article/details/111423923