非递归实现二叉树的前中后序遍历和层次遍历

前中后序遍历的非递归实现均采用栈结构实现,层次遍历采用队列实现。

先序遍历:

思路:

1最开始根节点入栈

2循环中每次向栈中取一个节点,访问该节点。将其左右子树入栈,直至栈为空为止。

注意:由于栈是先进后出的数据结构,先将右子树入栈,再将左子树入栈,才能得到中左右的访问顺序。

代码:

    //先序遍历
    public static void travelFirst(TreeNode root){
        Stack<TreeNode> stack = new Stack();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            System.out.println(node.val);
            if(node.right!=null){
                stack.push(node.right);
            }
            if(node.left!=null){
                stack.push(node.left);
            }
        }
    }

中序遍历:

思路:采用和后序遍历一样的思路,借鉴了https://www.cnblogs.com/rain-lei/p/3705680.html中实现后序遍历的方法2.

每次节点入栈都入栈两次,循环中每次都取一个节点,取出后如果该节点等于栈顶节点,表示该节点的左右子树还未访问,则先该节点左子树入栈,否则直接访问该节点,然后将右子树入栈。

代码:

//中序遍历
    public static void travelMid(TreeNode root) {
        Stack<TreeNode> stack = new Stack();
        stack.push(root);
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            if (stack.size() > 0 && node == stack.peek()) {
                if (node.left != null) {
                    stack.push(node.left);
                    stack.push(node.left);
                }
            } else {
                System.out.println(node.val);
                if (node.right != null) {
                    stack.push(node.right);
                    stack.push(node.right);
                }
            }
        }
    }

后序遍历:

思路;后序遍历的思路和中序类似。

每次节点入栈都入栈两次,循环中每次都取一个节点,取出后如果该节点等于栈顶节点,表示该节点的左右子树还未访问,则先该节点左子树入栈,然后将右子树入栈,否则直接访问该节点。

代码:

//后序遍历
    public static void travelLast(TreeNode root) {
        Stack<TreeNode> stack = new Stack();
        stack.push(root);
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            if (stack.size() > 0 && node == stack.peek()) {
                if (node.right != null) {
                    stack.push(node.right);
                    stack.push(node.right);
                }
                if (node.left != null) {
                    stack.push(node.left);
                    stack.push(node.left);
                }
            } else {
                System.out.println(node.val);
            }


        }
    }

层次遍历:

思路:按照树的深度依次向下遍历,采用队列(本例中采用linkedlist实现队列)作为辅助结构。

1将根节点入队

2循环从队列中取出元素,访问该元素,并将该元素左右节点入队,直到队列为空。

    //层次遍历
    public static void travelLevel(TreeNode root){
        LinkedList<TreeNode> list = new LinkedList();
        list.offer(root);
        while(!list.isEmpty()){
            TreeNode node = list.poll();
            System.out.println(node.val);
            if(node.left!=null) {
                list.offer(node.left);
            }
            if(node.right!=null){
                list.offer(node.right);
            }
        }
    }

 

 

测试代码:

    public static void main(String[] args) {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(5);
        TreeNode node6 = new TreeNode(6);
        TreeNode node7 = new TreeNode(7);
        node1.left = node2;
        node1.right = node3;
        node2.left = node4;
        node2.right = node5;
        node3.left = node6;
        node3.right = node7;
        travelLevel(node1);
    }


    public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }

附一个非递归获取树深度的方法(基于层次遍历)

思路:与层次遍历不同的是,每次入队(最外层一次循环)都将上一层的节点全都出队(借助变量len实现),使得每次循环中队列中都只有一层的节点,则每次循环depth都加1。

//通过层次遍历来得到树的深度
    public static int treeDepthByLevel(TreeNode root){
        LinkedList<TreeNode> list = new LinkedList();
        list.offer(root);
        int depth = 0;
        while(!list.isEmpty()){
            int len = list.size();
            depth++;
            while((len--)>0){
                TreeNode node = list.poll();
                if(node.left!=null){
                    list.offer(node.left);
                }
                if(node.right!=null){
                    list.offer(node.right);
                }
            }
        }
        return depth;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值