Four ways to traverse binary trees

Four ways to traverse the binary tree:

  • Traversing binary tree refers to starting from the root node, visiting all the nodes in the binary tree in a certain order, so that each node is visited sequentially and only once.
    The four traversal methods are: first-order traversal, middle-order traversal, post-order traversal, and layer-order traversal.

 

Before traversing, we first introduce how to create a binary tree. Here we use the method of building the left tree first and then building the right tree.

First, we must declare the node TreeNode class, the code is as follows:

Copy code

public class TreeNode {
    public int data;
    public TreeNode leftChild;
    public TreeNode rightChild;

    public TreeNode(int data){
        this.data = data;
    }

}

Copy code

Let's create a binary tree:

Copy code

/**
     * Build a binary tree
     * @param list input sequence
     * @return
     */
    public static TreeNode createBinaryTree(LinkedList<Integer> list){
        TreeNode node = null;
        if(list == null || list.isEmpty()){
            return null;
        }
        Integer data = list.removeFirst();
        if(data!=null){
            node = new TreeNode(data);
            node.leftChild = createBinaryTree(list);
            node.rightChild = createBinaryTree(list);
        }
        return node;
    }

Copy code

Next, explain them one by one in the order listed above,

First look at the preorder traversal. The so-called preorder traversal is to visit the root node first, then the left node, and finally the right node.

As shown in the figure above, the result of the preorder traversal is: ABDFECGHI

The implementation code is as follows:

Copy code

/**
     * Binary tree preorder traversal root -> left -> right
     * @param node Binary tree node
     */
    public static void preOrderTraveral(TreeNode node){
        if(node == null){
            return;
        }
        System.out.print(node.data+" ");
        preOrderTraveral(node.leftChild);
        preOrderTraveral(node.rightChild);
    }

Copy code

The second is the middle-order traversal. The so-called middle-order traversal is to visit the left node first, then the root node, and finally the right node.

 

 

As shown in the figure above, the middle order traversal result is: DBEFAGHCI

The implementation code is as follows:

Copy code

/**
     * Binary tree middle order traversal left -> root -> right
     * @param node Binary tree node
     */
    public static void inOrderTraveral(TreeNode node){
        if(node == null){
            return;
        }
        inOrderTraveral(node.leftChild);
        System.out.print(node.data+" ");
        inOrderTraveral(node.rightChild);
    }

Copy code

The last is post-order traversal. The so-called post-order traversal is to visit the left node first, then the right node, and finally the root node.

 

 

As shown in the figure above, the post-order traversal result is: DEFBHGICA

The implementation code is as follows:

Copy code

/**
     * Post-order traversal of binary tree left -> right -> root
     * @param node Binary tree node
     */
    public static void postOrderTraveral(TreeNode node){
        if(node == null){
            return;
        }
        postOrderTraveral(node.leftChild);
        postOrderTraveral(node.rightChild);
        System.out.print(node.data+" ");
    }

Copy code

After talking about the above three recursive methods, let’s talk about how non-recursive traversal is realized.

Still the same, first look at the non-recursive preorder traversal

  1. First apply for a new stack, record it as stack;
  2. Declare a node treeNode, let it point to the node node;
  3. If treeNode is not empty, print the value of treeNode and push treeNode onto the stack, and then make treeNode point to the right node of treeNode,
  4. Repeat step 3 until treenode is empty;
  5. Then pop the stack and let treeNode point to the right child of treeNode
  6. Repeat step 3 until the stack is empty.

The implementation code is as follows:

Copy code

public static void preOrderTraveralWithStack(TreeNode node){
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode treeNode = node;
        while(treeNode!=null || !stack.isEmpty()){
            //Iteratively visit the left child of the node and merge it onto the stack
            while(treeNode != null){
                System.out.print(treeNode.data+" ");
                stack.push(treeNode);
                treeNode = treeNode.leftChild;
            }
            //If the node has no left child, pop the top node of the stack and visit the right child of the node
            if(!stack.isEmpty()){
                treeNode = stack.pop();
                treeNode = treeNode.rightChild;
            }
        }
    }

Copy code

Mid-order traversal is non-recursive, so I won’t describe the specific steps here.

Specific process:

  1. Apply for a new stack, mark it as stack, apply for a variable cur, and initially set treeNode as the head node;
  2. First push the treeNode node into the stack. For the entire subtree headed by the treeNode node, push the left subtree of the entire tree into the stack in turn, that is, keep treeNode=treeNode.leftChild, and then repeat step 2;
  3. Repeat step 2 until it is found that cur is empty. At this time, a node pops up from the stack as treeNode, print the value of node, and let treeNode = treeNode.right, and then continue to repeat step 2;
  4. End when stack is empty and cur is empty.

Copy code

public static void inOrderTraveralWithStack(TreeNode node){
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode treeNode = node;
        while(treeNode!=null || !stack.isEmpty()){
            while(treeNode != null){
                stack.push(treeNode);
                treeNode = treeNode.leftChild;
            }
            if(!stack.isEmpty()){
                treeNode = stack.pop();
                System.out.print(treeNode.data+" ");
                treeNode = treeNode.rightChild;
            }

        }
    }

Copy code

Post-order traversal is not implemented recursively. Post-order traversal is a bit more complicated than the previous two implementations. We need a marker bit to remember a node on our node at this time. See the code comments for details.

Copy code

public static void postOrderTraveralWithStack(TreeNode node){
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode treeNode = node;
        TreeNode lastVisit = null; //Mark the last visited node for each traversal
        while(treeNode!=null || !stack.isEmpty()){//The node is not empty, the node is on the stack, and points to the next left child
            while(treeNode!=null){
                stack.push(treeNode);
                treeNode = treeNode.leftChild;
            }
            //The stack is not empty
            if(!stack.isEmpty()){
                //Pull
                treeNode = stack.pop();
                /**
                 * This block is to determine whether treeNode has a right child,
                 * If treeNode.data is not output, let lastVisit point to treeNode and let treeNode be empty
                 * If there is a right child, continue the current node into the stack, treeNode points to its right child, and continue to repeat the loop
                 */
                if(treeNode.rightChild == null || treeNode.rightChild == lastVisit) {
                    System.out.print(treeNode.data + " ");
                    lastVisit = treeNode;
                    treeNode  = null;
                }else{
                    stack.push(treeNode);
                    treeNode = treeNode.rightChild;
                }

            }

        }
    }

Copy code

Finally, I will introduce you to layer sequence traversal

Specific steps are as follows:

  1. First apply for a new queue and record it as queue;
  2. Press the head node head into the queue;
  3. Every time you leave the queue, record it as node, and then print the value of node. If the left child of node is not empty, the left child will be enqueued; if the right child of node is not empty, the right child will be enqueued;
  4. Repeat step 3 until the queue is empty.

The implementation code is as follows:

Copy code

public static void levelOrder(TreeNode root){
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while(!queue.isEmpty()){
            root = queue.pop();
            System.out.print(root.data+" ");
            if(root.leftChild!=null) queue.add(root.leftChild);
            if(root.rightChild!=null) queue.add(root.rightChild);
        }
    }

Copy code

 

Category:  Tree

Guess you like

Origin blog.csdn.net/sd19871122/article/details/108075879