【代码随想录刷题】二叉树01~05总结

在这里插入图片描述

1. 二叉树01

【代码随想录刷题】Day14二叉树01

从这天开始学习了二叉树的内容

首先学习了关于二叉树的理论基础:

【代码随想录刷题】二叉树的理论基础
【代码随想录刷题】二叉树的实现java版

  • 树是一种抽象数据类型(ADT),是一种非线性数据结构。
  • 关于树的一些相关概念,如:节点的度、树的度、节点的深度以及树的高度等等。
  • 树的存储形式主要有:双亲表示法、孩子表示法、孩子兄弟表示法,常用的是孩子兄弟表示法。
  • 树的应用:linux 系统。

二叉树

  • 是 n 个有限元素的集合
  • 在我们解题过程中二叉树有两种主要的形式:满二叉树和完全二叉树。
  • 二叉搜索树是一个有序树。
    • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
    • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
    • 它的左、右子树也分别为二叉排序树。
  • 平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
  • 二叉树的存储方式:可以链式存储,也可以顺序存储。我们一般是用链式来存储二叉树。
  • 二叉树的遍历方式:
    • 深度优先遍历
      • 前序遍历(递归,迭代) 节点顺序:根左右
      • 中序遍历(递归,迭代) 节点顺序:左根右
      • 后序遍历(递归,迭代) 节点顺序:左右根
    • 广度优先遍历
      • 层次遍历(迭代)

然后学习了递归遍历的思路:

递归三部曲:

  • 1.确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
  • 2.确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
  • 3.确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

最后用二叉树的前序、后序、中序遍历来练手。
(遍历可以用递归和迭代来实现,但是优先掌握递归)

2. 二叉树02

【代码随想录刷题】Day15 二叉树02

这天主要一口气打了10道层次遍历的题目:

【代码随想录刷题】一口气打10道层次遍历 打打打

层序遍历的思路:

  • 层序遍历一个二叉树,就是从左到右一层一层的去遍历二叉树。
  • 需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
  • 而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。

然后还刷了【226】翻转二叉树这道题的关键在于遍历顺序,前中后序应该选哪一种遍历顺序?

  • 注意只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果
  • 这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转了两次
  • 因为中序先左孩子交换孩子,再根交换孩子(做完后,右孩子已经变成了原来的左孩子), 再右孩子交换孩子(此时其实是对原来的左孩子做交换)
  • 层序遍历也可以

最后刷了【101】对称二叉树,这道题目需要检查这棵二叉树是否对称。

首先我们要想清楚,判断对称二叉树要比较的是哪两个节点,要比较的可不是左右节点!

对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的。其实我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。

我们需要比较的是两个子树的里侧和外侧的元素是否相等。如图所示:
请添加图片描述

3. 二叉树03

【代码随想录刷题】Day16 二叉树03

这天深入学习了二叉树节点的深度和二叉树节点的高度。

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
  • 前序求深度,后序求高度。
    请添加图片描述
  • 对于【104】二叉树的最大深度,其实根节点的高度就是二叉树的最大深度,所以本题中我们可以通过后序遍历求的根节点高度来求二叉树的最大深度。
    • 在前一天做这道题目时,使用的是层次遍历法,那是因为最大的深度就是二叉树的层数,两者正好相等。
  • 对于【111】二叉树的最小深度,此题的重点在于读懂题意,理解最小深度最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
  • 对于【222】完全二叉树的节点个数,这道题使用递归法,把左右子树节点数相加再加1就可(这个1指的是根节点);使用层次遍历把每层遍历到的节点数相加即可。

4. 二叉树04

【代码随想录刷题】Day17 二叉树04

  • 对于【110】平衡二叉树,首先要知道平衡二叉树的定义:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
    • 既然让比较高度,那么要用后序遍历。分别求出其左右子树的高度,然后判断其差值是否小于等于1。
  • 对于【257】二叉树的所有路径,要求按 任意顺序 ,返回所有从根节点到叶子节点的路径。
    • 在这道题目中,首次接触到回溯。 我们要把路径记录下来,需要回溯来回退一个路径再进入另一个路径。
    • 要知道递归和回溯是一家的,本题使用递归的方式,也需要回溯。

第一次在二叉树中接触到回溯,关于本题的详解可以看一下卡哥的视频,视频讲解的很清楚。

递归中带着回溯,你感受到了没?| LeetCode:257. 二叉树的所有路径

前序遍历以及回溯的过程如图:
请添加图片描述

  • 对于【404】左叶子之和,首先要知道什么是左叶子
    • 卡哥给出的左叶子的明确定义:节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点
    • 那么,我们如何来判断左叶子呢?判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。
    • 也就是说,如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子。

请添加图片描述

5.二叉树05

【代码随想录刷题】Day18 二叉树05

  • 对于【513】找树左下角的值,找出该二叉树的 最底层 最左边 节点的值。

    • 本题使用迭代法很简单,只需要记录最后一行第一个节点的数值就可以了。
    • 那么使用递归法呢?
      • 问题1:如何判断是最后一行。其实就是深度最大的叶子节点一定是最后一行。所以要找深度最大的叶子节点。
      • 问题2:如何找最左边的呢?可以使用前序遍历(当然中序,后序都可以,因为本题没有 根节点的处理逻辑,只要左优先就行),保证优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。
    • 此题也是用到了回溯。
  • 对于【112】路径总和,判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。

    • 本题可以采用深度遍历的方式来遍历(本题前中后序都可以,无所谓,因为根节点也没有处理逻辑)。,递归法请添加图片描述
  • 对于【106】从中序与后序遍历序列构造二叉树

    • 解这道题首先要知道中序遍历与后序遍历构造二叉树的理论知识:以 后续数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后续数组。一层一层的切下去,每次后续数组的最后一个元素就是节点元素。
    • 代码实现过程:
        1. 如果数组大小为0的话,说明是空节点了
        1. 如果不为空,那么取后序数组的最后一个元素作为节点元素
        1. 找到后序数组最后一个元素在中序数组中的位置,作为切割点
        1. 切割中序数组,切成中序左数组和中序右数组(顺序一定不能弄反了,一定要先切中序数组)
        1. 切割后序数组,切成后序左数组和后序右数组
        1. 递归处理左区间和右区间

中序遍历与后序遍历构造二叉树的流程如下图所示:
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值