0
点赞
收藏
分享

微信扫一扫

微信小程序本地生活(列表页面)

年迈的代码机器 2023-09-17 阅读 55
算法

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【二叉树的遍历】,使用【二叉树】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了LeetCode的来源),确保刷的题都是高频要面试考的题。

在这里插入图片描述
就着这两个高频题目把二叉树的遍历类型题目刷一遍
在这里插入图片描述

名曲目标题后,附上题目链接,后期可以依据解题思路反复快速练习,题目按照题干的基本数据结构分类,且每个分类的第一篇必定是对基础数据结构的介绍

二叉树的前序遍历【EASY】

前序、中序、后序都有迭代和递归的实现方式

题干

直接粘题干和用例

解题思路

前序遍历简单来说就是“根左右”,展开来说就是对于一颗二叉树优先访问其根节点,然后访问它的左子树,等左子树全部访问完了再访问其右子树,而对于子树也按照之前的访问方式,直到到达叶子节点,每次访问一个节点之后,它的左子树是一个要前序遍历的子问题,它的右子树同样是一个要前序遍历的子问题。那我们可以用递归处理:

  • 终止条件: 当子问题到达叶子节点后,后一个不管左右都是空,因此遇到空节点就返回
  • 返回值: 每次处理完子问题后,就是将子问题访问过的元素返回,依次存入了数组中
  • 本级任务: 每个子问题优先访问这棵子树的根节点,然后递归进入左子树和右子树

具体做法:
step 1:准备数组用来记录遍历到的节点值,Java可以用List
step 2:从根节点开始进入递归,遇到空节点就返回,否则将该节点值加入数组。
step 3:依次进入左右子树进行递归。

代码实现

给出代码实现基本档案

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类
     * @return int整型一维数组
     */
    public int[] preorderTraversal (TreeNode root) {
        // 1 定义用来返回的数据
        List<Integer> list = new ArrayList<>();
        // 2 递归填充list的值
        preorder(list, root);
        // 3 返回结果处理
        int[] result = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            result[i] = list.get(i);
        }
        return result;
    }

    private void preorder(List<Integer> list, TreeNode root) {
        // 1 递归终止条件
        if (root == null) {
            return;
        }
        // 2 按顺序递归填充左右子树
        list.add(root.val);
        preorder(list, root.left);
        preorder(list, root.right);
    }
}

复杂度分析

时间复杂度:遍历了N个节点,所以时间复杂度为O(N)
空间复杂度:最坏情况下,树退化为链表,递归栈深度为N,所以空间复杂度为O(N)

二叉树的中序遍历【EASY】

换位中序遍历

题干

直接粘题干和用例

解题思路

如果一棵二叉树,对于每个根节点都优先访问左子树,那结果是什么?从根节点开始不断往左,第一个被访问的肯定是最左边的节点。然后访问该节点的右子树,最后向上回到父问题。因为每次访问最左的元素不止对一整棵二叉树成立,而是对所有子问题都成立,因此循环的时候自然最开始都是遍历到最左,然后访问,然后再进入右子树,我们可以用栈来实现回归父问题

  1. 寻找最左子树,此过程逐层将树及左子树的根节点压入栈中,把要后处理的上层子树根节点先压入操作栈
  2. 栈顶即当前最左子树根节点,也是上层子树的左子节点,将值放入到list
  3. 节点指针移动到当前指针右节点,如果右节点为空,则本层处理完成,栈再弹出上层节点,接着循环处理

其实思路与递归就相似了,只不过将递归栈具象化了

代码实现

递归的思路和代码不再赘述,直接给出

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类
     * @return int整型一维数组
     */
    public int[] inorderTraversal (TreeNode root) {
        // 1 定义入参和返回值
        List<Integer> list = new ArrayList<>();
        // 2 中序递归获取list
        inorder(list, root);
        // 3 list结果转换
        int[] result = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            result[i] = list.get(i);
        }
        return result;
    }

    private void inorder(List<Integer> list, TreeNode root) {
        // 1 终止条件
        if (root == null) {
            return;
        }

        inorder(list, root.left);
        list.add(root.val);
        inorder(list, root.right);
    }
}

给出代码实现基本档案

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类
     * @return int整型一维数组
     */
    public int[] inorderTraversal (TreeNode root) {
        // 1 定义入参和辅助栈
        List<Integer> list = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<TreeNode>();
        if (root == null) {
            return new int[0];
        }
        // 2 寻找最左子树
        TreeNode tempRoot = root;
        while (tempRoot != null || !stack.isEmpty()) {
            // 2-1 寻找最左子树,此过程逐层将树及左子树的根节点压入栈中
            while (tempRoot != null) {
                // 把要后处理的上层子树根节点先压入操作栈
                stack.push(tempRoot);
                tempRoot = tempRoot.left;
            }
            // 2-2 栈顶即当前最左子树根节点,也是上层子树的左子节点
            TreeNode node = stack.pop();
            list.add(node.val);
            // 2-3 节点指针移动到当前指针右节点,如果右节点为空,则本层处理完成,栈再弹出上层节点
            tempRoot = node.right;
        }
        // 3 list结果转换
        int[] result = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            result[i] = list.get(i);
        }
        return result;
    }
}

复杂度分析

时间复杂度:遍历了N个节点,所以时间复杂度为O(N)
空间复杂度:最坏情况下,树退化为链表,辅助递归栈深度为N,所以空间复杂度为O(N)

二叉树的后序遍历【EASY】

ok,再来看二叉树的后序遍历

题干

直接粘题干和用例

解题思路

左右根,同前序遍历及中序遍历的递归解法,不再赘述

代码实现

给出代码实现基本档案

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类
     * @return int整型一维数组
     */
    public int[] postorderTraversal (TreeNode root) {
        // 1 定义用来返回的数据
        List<Integer> list = new ArrayList<>();
        // 2 递归填充list的值
        postorder(list, root);
        // 3 返回结果处理
        int[] result = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            result[i] = list.get(i);
        }
        return result;
    }

    private void postorder(List<Integer> list, TreeNode root) {
        if (root == null) {
            return;
        }
        postorder(list, root.left);
        postorder(list, root.right);
        list.add(root.val);

    }
}

复杂度分析

时间复杂度:遍历了N个节点,所以时间复杂度为O(N)
空间复杂度:最坏情况下,树退化为链表,递归栈深度为N,所以空间复杂度为O(N)

二叉树的层序遍历【MID】

题干

直接粘题干和用例

解题思路

给出解题思路,最好有图

代码实现

给出代码实现基本档案

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

复杂度分析

时间复杂度:
空间复杂度:

二叉树的锯齿形层序遍历【MID】

题干

直接粘题干和用例

解题思路

给出解题思路,最好有图

代码实现

给出代码实现基本档案

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

复杂度分析

时间复杂度:
空间复杂度:

二叉树的右视图【MID】

题干

直接粘题干和用例

解题思路

给出解题思路,最好有图

代码实现

给出代码实现基本档案

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

复杂度分析

时间复杂度:
空间复杂度:

拓展知识

关联与本题相关的辅助知识点

举报

相关推荐

0 条评论