Pre-, post-order and level-order traversal of binary trees (recursive and non-recursive methods)

1. Preorder traversal

Preorder traversal is a method of binary tree traversal, also known as preorder traversal. The traversal rule is: root node → left subtree → right subtree. The preorder traversal of the binary tree is implemented by recursive and non-recursive methods as follows.

1.1 Recursive method

class Solution {
   List<Integer> res=new ArrayList<>();
    public List<Integer> preorderTraversal(TreeNode root) {
        if(root!=null){
            res.add(root.val);         
            preorderTraversal(root.left);        //递归遍历左子树
            preorderTraversal(root.right);       //递归遍历右子树
        }
        return res;
    }
}

1.2 Non-recursive methods

Idea : Consider using the stack to implement the preorder non-recursive implementation method of the binary tree, push the root node into the stack, and store it in the list; then access the left subtree of the root node, which is also the root of the left subtree Store it in the stack and store it in the list, go down in sequence until the left subtree is empty, and then take out the top element of the stack, and the top element of the stack is used as a new root node to access the right subtree.

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new LinkedList<>();
        Stack<TreeNode> stack = new Stack<>();//用一个栈来存放树中的节点
        while(root != null || !stack.isEmpty()) {

            while (root != null) {                 
                stack.push(root);                //根节点入栈
                
                result.add(root.val);

                root = root.left;             //访问左子树
            }
            root = stack.pop();           //取出根节点
            root = root.right;              //访问右子树
        }
        return result;
    }
}

2. Inorder traversal

The rules of inorder traversal: left subtree → root node → right subtree. It is slightly more difficult than the method of preorder traversal. Because in the binary tree visit, the root node is first encountered, but in in-order traversal, the first visit is the left node. Also, it is easier to implement in-order traversal by recursive method.

2.1 Recursive method

class Solution {
    List<Integer> res=new ArrayList<>();
    public List<Integer> inorderTraversal(TreeNode root) {
        if(root != null){
            inorderTraversal(root.left);
            res.add(root.val);
            inorderTraversal(root.right);
        }
        return res;
    }
}

2.2 Non-recursive methods

Idea : The idea of ​​using the stack is the same as that of 1.2. It can be realized by adjusting the code position of adding the node to the list.

class Solution {
	public List<Integer> inorderTraversal(TreeNode root) {
	List<Integer> result = new LinkedList<>();
	Stack<TreeNode> stack = new Stack<>();//用一个栈来存放树中的节点
	while(root!=null || !stack.isEmpty()){
		while(root != null){
			stack.push(root);
			root = root.left;
		}
		root = stack.pop();
		result.add(root.val);
		root = root.right;
	}
	return result;
    }
}

3. Post-order traversal

The rules of inorder traversal: left subtree → right subtree → root node. Compared with the first two traversal methods, post-order traversal is the most difficult way to understand, and we first implement it by recursive method.

3.1 Recursive methods

class Solution {
    List<Integer> res=new ArrayList<>();
    public List<Integer> postorderTraversal(TreeNode root) {
          if(root != null){
            postorderTraversal(root.left);
            postorderTraversal(root.right);
            res.add(root.val);
        }
        return res;
    }
}

3.2 Non-recursive methods

class Solution {
    
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        Stack<TreeNode> stack = new Stack<>();
        TreeNode pre = null;
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.push(root); 
                root = root.left;
            }
            root = stack.peek(); 

            if (root.right == null || root.right == pre ) { 
                stack.pop();
                res.add(root.val);
                pre = root;
                root = null;
            } else {
                root = root.right; 
            }
        }
        return res;
    }
}

This problem still considers using the stack method to solve the problem, the difference is the introduction of pre and peek. First, push the root node and the left subtree node into the stack, knowing that the left node is empty; then use stack.peek to return the top element of the stack to determine whether the right node is empty, if not, traverse the right node and add it to the stack; If it is empty, return the element of the stack, remove it, and add it to the res queue. The pre parameter is introduced to store the current root node. The function here is as shown in the figure.
insert image description here
Pre is used to store the current root node. In the operation of adding A to the queue, it is judged whether its right node C has been processed, so as to avoid repeated processing.

4. Layer order traversal

The rules of level-order traversal are very simple. According to the structure of the binary tree,
insert image description here
it is traversed from top to bottom and from left to right . The node enters the queue, and then enters the loop to determine whether the queue is empty. If it is not empty, the first element of the queue is dequeued and stored in the result list; then its left and right child nodes are put into the queue, and the loop is judged. . If empty, output the result.

 public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if(root == null){
            return result;
        }

        Queue<TreeNode> queue = new ArrayDeque<>();
        queue.add(root);

        while (!queue.isEmpty()){
            List<Integer> level = new ArrayList<Integer>();
            int Size = queue.size();
            for(int i = 1; i <= Size; i++){
                TreeNode node = queue.poll();
                level.add(node.val);
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
            result.add(level);
        }
        return result;
    }
    ```

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325258287&siteId=291194637