Files
leetcode-master/problems/周总结/20201017二叉树周末总结.md
2025-05-19 17:11:04 +08:00

120 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 本周小结!(二叉树系列四)
> 这已经是二叉树的第四周总结了,二叉树是非常重要的数据结构,也是面试中的常客,所以有必要一步一步帮助大家彻底掌握二叉树!
## 周一
在[二叉树:合并两个二叉树](https://programmercarl.com/0617.合并二叉树.html)中讲解了如何合并两个二叉树,平时我们都习惯了操作一个二叉树,一起操作两个树可能还有点陌生。
其实套路是一样,只不过一起操作两个树的指针,我们之前讲过求 [二叉树:我对称么?](https://programmercarl.com/0101.对称二叉树.html)的时候,已经初步涉及到了 一起遍历两棵二叉树了。
**迭代法中,一般一起操作两个树都是使用队列模拟类似层序遍历,同时处理两个树的节点,这种方式最好理解,如果用模拟递归的思路的话,要复杂一些。**
## 周二
周二开始讲解一个新的树,二叉搜索树,开始要换一个思路了,如果没有利用好二叉搜索树的特性,就容易把简单题做成了难题了。
学习[二叉搜索树的特性](https://programmercarl.com/0700.二叉搜索树中的搜索.html),还是比较容易的。
大多是二叉搜索树的题目,其实都离不开中序遍历,因为这样就是有序的。
至于迭代法,相信大家看到文章中如此简单的迭代法的时候,都会感动的痛哭流涕。
## 周三
了解了二搜索树的特性之后, 开始验证[一棵二叉树是不是二叉搜索树](https://programmercarl.com/0098.验证二叉搜索树.html)。
首先在此强调一下二叉搜索树的特性:
* 节点的左子树只包含小于当前节点的数。
* 节点的右子树只包含大于当前节点的数。
* 所有左子树和右子树自身必须也是二叉搜索树。
那么我们在验证二叉搜索树的时候,有两个陷阱:
* 陷阱一
**不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了**,而是左子树都小于中间节点,右子树都大于中间节点。
* 陷阱二
在一个有序序列求最值的时候不要定义一个全局变量然后遍历序列更新全局变量求最值。因为最值可能就是int 或者 longlong的最小值。
推荐要通过前一个数值pre和后一个数值比较cur得出最值。
**在二叉树中通过两个前后指针作比较,会经常用到**
本文[二叉树:我是不是一棵二叉搜索树](https://programmercarl.com/0098.验证二叉搜索树.html)中迭代法中为什么没有周一那篇那么简洁了呢,因为本篇是验证二叉搜索树,前提默认它是一棵普通二叉树,所以还是要回归之前老办法。
## 周四
了解了[二叉搜索树](https://programmercarl.com/0700.二叉搜索树中的搜索.html),并且知道[如何判断二叉搜索树](https://programmercarl.com/0098.验证二叉搜索树.html),本篇就很简单了。
**要知道二叉搜索树和中序遍历是好朋友!**
在[二叉树:搜索树的最小绝对差](https://programmercarl.com/0530.二叉搜索树的最小绝对差.html)中强调了要利用搜索树的特性,把这道题目想象成在一个有序数组上求两个数最小差值,这就是一道送分题了。
**需要明确:在有序数组求任意两数最小值差等价于相邻两数的最小值差**
同样本题也需要用pre节点记录cur节点的前一个节点。这种写法一定要掌握
## 周五
此时大家应该知道遇到二叉搜索树,就想是有序数组,那么在二叉搜索树中求二叉搜索树众数就很简单了。
在[二叉树:我的众数是多少?](https://programmercarl.com/0501.二叉搜索树中的众数.html)中我给出了如果是普通二叉树,应该如何求众数的集合,然后进一步讲解了二叉搜索树应该如何求众数集合。
在求众数集合的时候有一个技巧,因为题目中众数是可以有多个的,所以一般的方法需要遍历两遍才能求出众数的集合。
**但可以遍历一遍就可以求众数集合,使用了适时清空结果集的方法**,这个方法还是很巧妙的。相信仔细读了文章的同学会惊呼其巧妙!
**所以大家不要看题目简单了,就不动手做了,我选的题目,一般不会简单到不用动手的程度**
## 周六
在[二叉树:公共祖先问题](https://programmercarl.com/0236.二叉树的最近公共祖先.html)中,我们开始讲解如何在二叉树中求公共祖先的问题,本来是打算和二叉搜索树一起讲的,但发现篇幅过长,所以先讲二叉树的公共祖先问题。
**如果找到一个节点发现左子树出现结点p右子树出现节点q或者 左子树出现结点q右子树出现节点p那么该节点就是节点p和q的最近公共祖先。**
这道题目的看代码比较简单,而且好像也挺好理解的,但是如果把每一个细节理解到位,还是不容易的。
主要思考如下几点:
* 如何从底向上遍历?
* 遍历整棵树,还是遍历局部树?
* 如何把结果传到根节点的?
这些问题都需要弄清楚,上来直接看代码的话,是可能想不到这些细节的。
公共祖先问题,还是有难度的,初学者还是需要慢慢消化!
## 总结
本周我们讲了[如何合并两个二叉树](https://programmercarl.com/0617.合并二叉树.html),了解了如何操作两个二叉树。
然后开始另一种树:二叉搜索树,了解[二叉搜索树的特性](https://programmercarl.com/0700.二叉搜索树中的搜索.html),然后[判断一棵二叉树是不是二叉搜索树](https://programmercarl.com/0098.验证二叉搜索树.html)。
了解以上知识之后,就开始利用其特性,做一些二叉搜索树上的题目,[求最小绝对差](https://programmercarl.com/0530.二叉搜索树的最小绝对差.html)[求众数集合](https://programmercarl.com/0501.二叉搜索树中的众数.html)。
接下来,开始求二叉树与二叉搜索树的公共祖先问题,单篇篇幅原因,先单独介绍[普通二叉树如何求最近公共祖先](https://programmercarl.com/0236.二叉树的最近公共祖先.html)。
现在已经讲过了几种二叉树了,二叉树,二叉平衡树,完全二叉树,二叉搜索树,后面还会有平衡二叉搜索树。 那么一些同学难免会有混乱了,我针对如下三个问题,帮大家在捋顺一遍:
1. 平衡二叉搜索树是不是二叉搜索树和平衡二叉树的结合?
是的,是二叉搜索树和平衡二叉树的结合。
2. 平衡二叉树与完全二叉树的区别在于底层节点的位置?
是的,完全二叉树底层必须是从左到右连续的,且次底层是满的。
3. 堆是完全二叉树和排序的结合,而不是平衡二叉搜索树?
堆是一棵完全二叉树,同时保证父子节点的顺序关系(有序)。 **但完全二叉树一定是平衡二叉树,堆的排序是父节点大于子节点,而搜索树是父节点大于左孩子,小于右孩子,所以堆不是平衡二叉搜索树**
大家如果每天坚持跟下来,会发现又是充实的一周![机智]
<div align="center"><img src='https://file1.kamacoder.com/i/algo/01二维码.jpg' width=450> </img></div>