树的遍历的三种方式(递归和非递归)(Java)

递归版:
先序遍历:

public static void preTraverse(TreeNode node,List<Integer> list){
    
    
        if(node==null)return;
        list.add(node.val);
        preTraverse(node.left,list);
        preTraverse(node.right,list);
    }

中序遍历:

public static void preTraverse(TreeNode node,List<Integer> list){
    
    
        if(node==null)return;
        preTraverse(node.left,list);
        list.add(node.val);
        preTraverse(node.right,list);
    }

后序遍历:

public static void preTraverse(TreeNode node,List<Integer> list){
    
    
        if(node==null)return;
        preTraverse(node.left,list);
        preTraverse(node.right,list);
        list.add(node.val);
    }

非递归版:
先序遍历:
利用栈先进后出的性质,先将所有节点的左节点压入栈如图,当8没有左节点的时候,就会把8取出来判断8有没有右节点,没有的话就把4取出来看看4有没有右节点,有的话再去找依次类推
在这里插入图片描述

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    
    
    public static List<Integer> inorderTraversal(TreeNode root) {
    
    
        List<Integer> list=new ArrayList<>();
        Stack<TreeNode> nodes=new Stack<>();
        TreeNode node=root;
        while (!nodes.empty() || node != null) {
    
    
            if (node != null) {
    
    
                nodes.push(node);
                //先输出再去找左,满足根->左->右
                list.add(node.val);
                node=node.left;
            }else{
    
    
                node=nodes.pop();
                node=node.right;
            }
        }
        return list;
    }
}

中序遍历:
中序遍历跟先序遍历一个原理遍历顺序相同输出位置不同

class Solution {
    
    
    public static List<Integer> inorderTraversal(TreeNode root) {
    
    
        List<Integer> list=new ArrayList<>();
        Stack<TreeNode> nodes=new Stack<>();
        TreeNode node=root;
        while (!nodes.empty() || node != null) {
    
    
            if (node != null) {
    
    
                nodes.push(node);
                node=node.left;
            }else{
    
    
                node=nodes.pop();
                 //因为栈里面都是左节点所以先拿出左输出再往下找,满足左->根->右
                list.add(node.val);
                node=node.right;
            }
        }
        return list;
    }
}

后序遍历:
后序遍历较之前的有点复杂,这里写一个双栈法,好理解好运用,包学包会。
思路:后序遍历就是左->右->根,于是可以用一个栈存储结果集,存储顺序为根->右->左,即跟先序遍历一个道理,根据栈先入后出的特性,得出左->右->根顺序

public static List<Integer> inorderTraversal(TreeNode root) {
    
    
        List<Integer> list=new ArrayList<>();
        Stack<TreeNode> nodes=new Stack<>();
        Stack<TreeNode> out=new Stack<>();
        TreeNode node=root;
        while(node!=null||!nodes.empty()){
    
    
            if (node != null) {
    
    
                nodes.push(node);
                out.push(node);
                node=node.right;
            }else{
    
    
                node=nodes.pop();
                node=node.left;
            }
        }
        while (!out.empty()){
    
    
            list.add(out.pop().val);
        }
        return list;
    }

猜你喜欢

转载自blog.csdn.net/weixin_43590593/article/details/112881011