二叉树的非递归遍历通用方法

在二叉树的非递归遍历上有很多种方法,但如果想要统一用一种通用方式来实现三者的非递归遍历还是很酷的.

树的结构
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int val) {
        this.val = val;
    }
}

递归遍历

递归遍历很简单,这是leetcode144的题

class Solutiont144 {
    ArrayList res = new ArrayList<>();
    public List preorderTraversal(TreeNode root) {
        if (root != null) {
            //递归模式只需要改变res.add的位置
            res.add(root.val);
            preorderTraversal(root.left);
            preorderTraversal(root.right);
        }
        return res;
    }
}

非递归遍历

借用Guide这个类,我习惯称之为"指令",在栈中压入一个"操作".

class generalPrintTree {
    public List preorderTraversal(TreeNode root) {
        ArrayList res = new ArrayList<>();
        Stack path = new Stack<>();

        path.push(new Guide(0, root));
        while (!path.isEmpty()) {
            Guide cur = path.pop();
            if (cur.node == null) continue;
            if (cur.ope == 1) { //当前指令是要输出,则输出(放到res里)
                res.add(cur.node.val);
            } else { //当前指令是要遍历这个node的子节点
                // 核心代码  ope = 1放在最后是前序, 1放在中间是中序, 1放在第一行是后序, 交换right和left位置可以是其他遍历方式
                path.push(new Guide(0, cur.node.right));
                path.push(new Guide(0, cur.node.left));
                path.push(new Guide(1, cur.node));
            }
        }
        return res;
    }

    class Guide {
        //Guide 可以认为是一个指令,这个指令里存有操作符ope 和node节点
        int ope = 0;  //0 ->visit, 1 ->print
        TreeNode node;

        public Guide(int ope, TreeNode node) {
            this.ope = ope;
            this.node = node;
        }
    }

}

以前序遍历为例:


二叉树的非递归遍历通用方法_第1张图片
image.png

而中序,后续遍历只要换核心的三行代码顺序就行了.准确的来说,如果只是前中后,那么只要换

 path.push(new Guide(1, cur.node));

这行代码就ok了.

你可能感兴趣的:(二叉树的非递归遍历通用方法)