LeetCode——树:层次遍历、前中后序遍历

LeetCode——树:层次遍历、前中后序遍历


目录

  1. 层次遍历
    1. 二叉树的层平均值
    2. 找树左下角的值
  2. 前中后序遍历
    1. 概述
    2. 非递归实现二叉树的前序遍历
    3. 非递归实现二叉树的中序遍历
    4. 非递归实现二叉树的后序遍历

1. 层次遍历

1. 二叉树的层平均值(LeetCode637)
  1. 概述
    1. 给定一个非空二叉树, 返回一个由每层节点平均值组成的数组.
    在这里插入图片描述
  2. 思路
    1. 利用广度优先搜索遍历整颗二叉树。
    2. 首先将它的根节点放入队列queue中,如果queue不为null,进入while循环
      1. 计算当前queue的size用于待会for循环遍历,创建变量sum记录每层的和
      2. queue.size.for循环,创建临时节点node存储queue弹出的元素,sum+=node.val。如果node.left或者right不为null,则加入队列
      3. 退出for循环,则得到了每层的值sum,该层节点个数cnt。相除即是结果
  3. 代码
public static List < Double > averageOfLevels(TreeNode root) {
        List<Double> ret = new ArrayList<>();
        if (root==null){
            return ret;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()){
            int cnt = queue.size();
            double sum = 0;
            for (int i = 0; i < cnt; i++) {
                TreeNode node = queue.poll();
                sum += node.val;
                if (node.left !=null)
                    queue.offer(node.left);
                if (node.right!=null)
                    queue.offer(node.right);
            }
            ret.add(sum/cnt);
        }
        return ret;
    }
  1. 小结
    1. 利用队列可以先遍历每一层的节点

2. 找树左下角的值(LeetCode513)
  1. 概述
    1. 给定一个二叉树,在树的最后一行找到最左边的值。
    在这里插入图片描述
  2. 思路
    1. 利用队列进行层次遍历,遍历过程加入队列时,先加右节点,再加左节点,这样队列每层出来的顺序就从右到左的
    2. 如果遍历加入队列时,是先加左节点,再加右节点,那么队列每层出来的顺序就是从左往右的
  3. 代码
public static int findBottomLeftValue(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            root = queue.poll();
            if (root.right != null)
                queue.offer(root.right);
            if (root.left != null)
                queue.offer(root.left);
        }
        return root.val;
    }

3. 前中后序遍历

0. 概述

在这里插入图片描述
1. 层次遍历顺序:[1,2,3,4,5,6]
2. 前序遍历顺序:[1,2,4,5,3,6]
3. 中序遍历顺序:[4,2,5,1,3,6]
4. 后序遍历顺序:[4,5,2,6,3,1]

  1. 层次遍历使用BFS实现,利用的就是BFS一层一层遍历的特性
  2. 而前序,中序,后序遍历利用了DFS实现。前序,中序,后序只是对节点访问的顺序有一点不同,其他都相同
  3. 递归版前序,中序,后序代码
public static void preOrderRecur(TreeNode head) {
        if (head == null) {
            return;
        }
        System.out.print(head.val + " ");
        preOrderRecur(head.left);
        preOrderRecur(head.right);
    }

    public static void inOrderRecur(TreeNode head) {
        if (head == null) {
            return;
        }
        inOrderRecur(head.left);
        System.out.print(head.val + " ");
        inOrderRecur(head.right);
    }

    public static void posOrderRecur(TreeNode head) {
        if (head == null) {
            return;
        }
        posOrderRecur(head.left);
        posOrderRecur(head.right);
        System.out.print(head.val + " ");
    }
1. 非递归实现二叉树的前序遍历
  1. 利用栈
    1. 利用栈先进后出的数据结构,可以对二叉树进行遍历。
    2. 先把head节点加入stack,当stack不为null时while循环stack,弹出栈顶元素,打印(因为前序遍历的顺序是:根左右,第一次遇到这个节点就打印)。
    3. 然后如果当前节点右孩子不为null,加入栈,左孩子不为null,加入栈,因为打印顺序是:根左右,所以加入顺序为根右左
    4. 代码实现
public static void preOrderUnRecur(TreeNode head) {
        if (head==null){
            return;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(head);
        while (!stack.isEmpty()){
            head = stack.pop();
            System.out.print(head.val+" ");
            if (head.right!=null)
                stack.push(head.right);
            if (head.left!=null)
                stack.push(head.left);
        }
    }
2. 非递归实现二叉树的中序遍历
  1. 利用栈
    1. 当栈不为null或者head!=null时,如果此时head!=null,则将它加入栈中,也就是将左边节点全部压入栈中
    2. 当head==null时,就会返回栈的最后一个元素,此时是第二次到达这个节点,所以就要打印(中序遍历:左中右,表示第二遇到这个节点就打印),然后跳到右节点
    3. 代码实现
public static void inOrderUnRecur(TreeNode head) {
        if (head != null) {
            Stack<TreeNode> stack = new Stack<>();
            while (!stack.isEmpty() || head != null) {
                if (head != null) {
                    stack.push(head);
                    head = head.left;
                } else {
                    head = stack.pop();
                    System.out.print(head.val + " ");
                    head = head.right;
                }
            }
        }
    }
3. 非递归实现二叉树的后序遍历
  1. 利用双栈
    1. 后序遍历的顺序为:左右中,我们知道前序遍历:中左右,当我们在前序遍历时先添加左节点,再添加右节点时,它的顺序就会变为中右左(栈的特性),这是我们将元素添加到另一个栈,打印出的顺序就为:左右中
    2. 代码实现
public static void posOrderUnRecur1(TreeNode head) {
        if (head!=null){
            Stack<TreeNode> s1 = new Stack<>();
            Stack<TreeNode> s2 = new Stack<>();
            s1.push(head);
            while (!s1.isEmpty()){
                head = s1.pop();
                s2.push(head);
                if (head.left!=null)
                    s1.push(head.left);
                if (head.right!=null)
                    s1.push(head.right);
            }
            while (!s2.isEmpty()){
                System.out.print(s2.pop().val+" ");
            }
        }
    }

补充:还有一种神奇的二叉树前中后序遍历算法——Morris遍历,有时间补充,之前总结过了,不过我也有点忘了…
二叉树的遍历(递归,非递归,Morris)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值