二叉树四种遍历方式总结——非递归

实现二叉树先序,中序,后序以及层序遍历

1、先序遍历

具体步骤:
1、创建一个栈和一个ArrayList。
2、先让根节点入栈。
3、当栈不为空时,栈顶出栈,并将出栈节点值保存到ArrayList中,然后再依次将出栈节点的右子节点,左子节点入栈。
ps:因为前序遍历要左子节点在右子节点前面,所以先入栈右子节点,后入栈左子节点(栈是先进后出)

代码展示:

public void preorder(TreeNode root,ArrayList<Integer> list){
        if(root == null) return;
        Stack<TreeNode> s = new Stack<>();
        s.push(root);
        while(!s.isEmpty()){
            TreeNode cur = s.pop();
            list.add(cur.val);
            if(cur.right!=null){
                s.push(cur.right);
            }
            if(cur.left!=null){
                s.push(cur.left);
            }
        }
    }

2、中序遍历

具体步骤:
1、创建一个栈和一个ArrayList。
2、先定义一个变量cur保存root节点;
3、当栈非空或者cur非空时,循环
3.1、当cur != null,说明此时cur还有左子节点,将cur节点入栈,并将cur置为它的左子节点位置上
3.2、当cur == null,说明此时已经走到了最左下节点,此时栈顶的父节点出栈赋值给cur,并将出栈节点的值保存在ArrayList中,然后将cur置为出栈节点的右子节点位置上,继续循环。

代码展示:
public void inorder(TreeNode root,ArrayList<Integer> list){
        if(root == null) return;
        Stack<TreeNode> s = new Stack<>();
        TreeNode cur = root;
        while(!s.isEmpty() || cur!=null){
            while(cur!=null){
                s.push(cur);
                cur = cur.left;
            }
                cur = s.pop();
                list.add(cur.val);
                cur = cur.right;
        }
    }

3、后序遍历

具体步骤:
1、创建一个栈和一个ArrayList。
2、先让根节点入栈。
3、当栈不为空时,将栈顶元素出栈,并且以头插的方式将出栈节点值插入到ArrayList中,然后依次将出栈节点的左子节点,右子节点入栈。

代码展示:

public void postorder(TreeNode root,ArrayList<Integer> list){
        if(root == null) return;
        Stack<TreeNode> s = new Stack<>();
        s.push(root);
        while(!s.isEmpty()){
            TreeNode cur = s.pop(); 
            list.add(0,cur.val);
            if(cur.left!=null){
                s.push(cur.left);
            }
            if(cur.right!=null){
                s.push(cur.right);
            }
        }
    }

4、层序遍历

具体步骤:
1、层序遍历相较于上面三种方式有些麻烦,它所用到的集合是队列,而且接收的话用一个ArrayList<ArrayList>来接收更好,因为每层遍历都需要一个集合来保存。
2、先将跟入队。
3、当队列非空时,记录当前队列的大小size,此时创建一个ArrayList创建for循环去将size个数添加到ArrayList中。for循环内部步骤:将队首出队,并将出队节点值加入到ArrayList中,再去依次判断其左右子节点是否为空,如果不为空,依次入队。(队列是先进先出)。然后将for循环执行完之后的ArrayList集合加入到ArrayList<ArrayList>中去。

代码展示:

public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
        // write code here
        ArrayList<ArrayList<Integer>> lists = new ArrayList<>();
        if(root==null) return lists;
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            ArrayList<Integer> newLevel = new ArrayList<>();
            for(int i=0;i<size;i++){
                TreeNode tmp = queue.poll();
                newLevel.add(tmp.val);
                if(tmp.left!=null){
                    queue.offer(tmp.left);
                }
                if(tmp.right!=null){
                    queue.offer(tmp.right);
                }
            }
            lists.add(newLevel);
        }
        return lists;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宋丹尼尔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值