后续会将纸质笔记的过程图更新上来。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v4boF5Zj-1663994025825)(/Users/yuguangyao/Library/Application Support/typora-user-images/image-20220821200515149.png)]
对于每一颗子树来说,它的左树的节点都比它小,它的右树的节点都比它大;
//一颗经典的搜索二叉树,你可以认为其中是没有重复值的。
//此即——经典的搜索二叉树~ ~。~
我用中序遍历的话 , 如果是搜索二叉树是一定不会降序的;——【而且】:一定会升序!!!
反之:
如果某一个位置有降序的话,那它一定不是搜索二叉树;
public class Code05_TestBST {
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static int preValue = Integer.MIN_VALUE;
public static boolean checkBST(Node headd) {
if (headd == null) {
return true;
}
boolean isLeftBst = checkBST(headd.left); //左树上是不是《搜索二叉树》???
if (!isLeftBst) {
return false;
}
if (headd.value <= preValue){
return false;
}else {
preValue = headd.value;
}
boolean isRightBst = checkBST(headd.right);
return isRightBst;
}
}
即使是最后一层不满,最后一层也是从左到右依次变满的样子。 //从左往右依次变满;
【1】:
如果有右孩子,但是没有左孩子,——则直接返回false.
【2】:
在第一个条件不违规的情况下: 如果遇到了第一个左右两个孩子不双全的情况,那么后续所有的节点都应当是叶子节点;
【最大深度】 : L
【节点个数】 : N
【满足关系】 : N = 2^L - 1
//如果满足上述的关系(N等于2的L次方),那么这棵树必定是满二叉树;
//如果不满足的话 , 这棵树肯定不是。
对于任何一个子树来说,它左树的高度和它右树的高度差都不会超过1. //对于每一个子树 ~
当我在求解一个二叉树问题的时候 , 我去列可能性的时候 , 怎么去列可能性. . . . . .
基于我可以向我的左树要某些信息,右树要某些信息的情况下,我怎么罗列可能性?
【1】:
左树得是平衡二叉树;
【2】:
右树也得是平衡二叉树;
【3】:
对于当前节点来说,我左树的高度和我右树的高度差不能超过1。 | 左高 - 右高 | <= 1
【#】:
只有上面的三个条件都成立 , 我整个的这个二叉树才是平衡二叉树 ~
【左树需要的信息】:
是否是平的(平衡二叉树) ? 高度是多少 ?
【右树需要的信息】:
是否是平的(平衡二叉树) ? 高度是多少 ?
【#】:
左树和右树要求是一样的。
我 X 为头的二叉树 , 是否是搜索二叉树 ?
「1」左树得是搜索二叉树
「2」右树得是搜索二叉树
「3」左树的Max < 根节点
「4」右树的Min > 根节点
//基于我可以向我的左树要某些信息 , 右树要某些信息的情况下, 我怎么罗列可能性:
【1】:
左树是否是搜索二叉树。(该树上的最大值)——Max
【2】:
右树是否是搜索二叉树。(该树上的最小值)——Min
[ # ] :
左右树的要求是不一样的 , 但我们又是递归套路 , 递归套路要求对每一个节点的要求都是一样的才叫递归。所以我不管你是左树/右树,一律给我返回三个信息。
(1)整棵树是否是搜索二叉树;
(2)整棵树Min。 //最小值是多少;
(3)整棵树Max。 //最大值是多少;
//在树上做动态规划。
//树的递归套路非常好用 , 能解决面试中的一切树型DP问题!!!
解一个题的时候可以通过向左树要信息,向右树要信息;
//排完序之后的中位数。——这种类型的题目就无法通过《二叉树套路》来解;
中位数信息是要结合所有情况来看的;
//中位数这种固定套路的可能不会在面试过程中出现~~~
这个套路不能解的题目,往往非常的麻烦 ~
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xccnACQn-1663994025826)(/Users/yuguangyao/Library/Application Support/typora-user-images/image-20220822152830950.png)]
//——————下面是:比较难理解的代码~~~
public static Node lowestAncestor(Node head, Node o1, Node o2) {
if (head == null || head == o1 || head == o2) { //base case
return head;
}
Node left = lowestAncestor(head.left, o1, o2); //左树的返回值;
Node right = lowestAncestor(head.right, o1, o2); //右树的返回值;
if (left != null && right != null) {
return head;
}
return left != null ? left : right;
}
如果一个树上既没有O1,又没有O2 , 那么它是一定会返回null的~
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EZG7FHeT-1663994025826)(/Users/yuguangyao/Library/Application Support/typora-user-images/image-20220823202441290.png)]
中序遍历中一个节点的下一个节点。
中序遍历结果:DBEAFCG
//所以我们说B的后继节点是E;
//E的后继节点是A。
//A的后继节点是F。
//G的后继节点是空。
中序遍历中一个节点的前一个节点。
经典二叉树中只有指左孩、右孩的指针,该题是有parent( 指向父节点 )指针的;
//每个parent指针都是好的,确实能正确地指向自己的父亲。
经典二叉树需要先中序遍历来得到一个list集合。
要遍历所有的节点来得到一个List ~。//这种方式的复杂度是 O(N)
X -----( 有K步 )-----> Y //前提是得有parent指针;
X节点到其后继节点Y之间有K步 , 则找到X节点的时间复杂度就是O( K );
//一个节点找后继,理论上是可以只走有限距离的。
原来可以偷懒(先中序遍历得到一个List集合。)
二叉树中最后一个节点是没有后继节点的,因为它所有的父亲都发现自己不是左分支( 一直到根节点 )。
//最后一个节点的后继节点是——Null .
我父亲的节点都走到空了 , 也没发现自己是父亲的左孩子。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EvZxk8tx-1663994025826)(/Users/yuguangyao/Library/Application Support/typora-user-images/image-20220823224419183.png)]
字符串要能够对应出唯一的结构来~
//一颗树的结构和值都能对应成一个唯一的字符串;
结构和字符串是一一对应的关系,不是多对多的关系。
//加下划线是表示一个值的结束;
//用#来表示空;
//先建立头节点,然后建立头节点的左子树,左子树建完了———再建右子树~~~!!!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d2Bu19Vc-1663994025826)(/Users/yuguangyao/Library/Application Support/typora-user-images/image-20220823232612033.png)]
【一次】:
O1
【二次】:
O2,O1,T2
【三次】:
O3,O2,T3,O1,O3,T2,T3
每一条折痕的上下都会出现一个新折痕,上凹下凸;
你想打印折痕的方向,就是对下图这棵二叉树作中序遍历:
//总树的头节点为凹折痕;
//每一颗左子树的头节点都是凹折痕;
//每一颗右子树的头节点都是凸折痕;