二叉树的前序、中序、后序遍历(非递归)

二叉树的遍历使用递归的方式会相对简单和理解,下面使用非递归的形式实现前序、中序、后序遍历。

如下二叉树:

二叉树的前序、中序、后序遍历(非递归)_第1张图片

前序遍历为: 124758369

中序遍历为: 742851693

后序遍历为: 748529631

使用非递归时,需要遍历到每个元素,所以能想到的实现方式为循环,由于不知道循环次数,所以考虑使用while循环,使用的数据结构为栈。

二叉树节点定义类:

public class TreeNode {
    private String data;

    private TreeNode left;

    private TreeNode right;

    public TreeNode(String data, TreeNode left, TreeNode right) {

        this.data = data;
        this.left = left;
        this.right = right;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public TreeNode getLeft() {
        return left;
    }

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

    public TreeNode getRight() {
        return right;
    }

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

 非递归前序遍历:

    public static List  pre1(TreeNode treeNode) {
       List list = new ArrayList<>();
        Stack stack = new Stack<>();
        if (treeNode!=null){
            stack.push(treeNode);
            while (!stack.isEmpty()){
                TreeNode pop = stack.pop();
                list.add(pop.getData());
                if(pop.getRight()!=null){
                    stack.push(pop.getRight());
                }
                if(pop.getLeft()!=null){
                    stack.push(pop.getLeft());
                }
            }
        }
        return list;
    }

前序遍历的顺序为根左右,为什么在循环中需要先添加右子节点,是因为栈的结构为先进后出,只有先添加右子节点,才能保证在出栈时保证先访问到左子节点,再访问到右子节点。

非递归中序遍历:

    // 左根右
    public  List in(TreeNode treeNode) {
        if (treeNode == null) {
            return null;
        }
        List res = new ArrayList<>();
        Stack stack = new Stack<>();
        TreeNode cur = treeNode;
        while (!stack.isEmpty() || cur!=null) {
            while (cur!=null){
                stack.push(cur);
                cur = cur.getLeft();
            }

            TreeNode pop = stack.pop();
            res.add(pop.getData());
            cur = pop.getRight();
        }
        return res;
    }

非递归后序遍历:

    // 左右根
    public  List post(TreeNode treeNode) {
        if (treeNode == null) {
            return null;
        }
        List res= new ArrayList<>();
        Stack stack = new Stack<>();
        TreeNode cur = treeNode;
        TreeNode t = null;
        while (!stack.isEmpty() || cur!=null) {
            if (cur!=null){
                stack.push(cur);
                cur = cur.getLeft();
            }else{
                //到这里已经到了最左边的节点 此时需要判断他的右节点有没有,或者等右节点打印之后
                TreeNode pop = stack.peek();
                if(pop.getRight()!=null && pop.getRight()!=t){
                    cur = pop.getRight();
                    stack.push(cur);
                    cur = cur.getLeft();
                }else{
                    cur = stack.pop();
                    res.add(cur.getData());
                    t = cur;
                    cur = null;
                }
            }
        }
        return res;
    }

你可能感兴趣的:(leetcode,数据结构,算法,二叉树)