数据结构与算法——左程云06

【前言】:

后续会将纸质笔记的过程图更新上来。

【1】:二叉树遗留

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v4boF5Zj-1663994025825)(/Users/yuguangyao/Library/Application Support/typora-user-images/image-20220821200515149.png)]

【搜索二叉树】:

对于每一颗子树来说,它的左树的节点都比它小,它的右树的节点都比它大;

//一颗经典的搜索二叉树,你可以认为其中是没有重复值的。

image-20220821200716919 //此即——经典的搜索二叉树~ ~。~

【如何判断一颗搜索二叉树呢?】:

我用中序遍历的话 , 如果是搜索二叉树是一定不会降序的;——【而且】:一定会升序!!!

反之:

​ 如果某一个位置有降序的话,那它一定不是搜索二叉树;

  • Code05_TestBST

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】:

​ 在第一个条件不违规的情况下: 如果遇到了第一个左右两个孩子不双全的情况,那么后续所有的节点都应当是叶子节点;

  • 《@@73_1》

【满二叉树】:

【最大深度】 :  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问题】:

//在树上做动态规划。

  • 二叉树题目中最难的,没有更难的了~ ~ ~

//树的递归套路非常好用 , 能解决面试中的一切树型DP问题!!!

【树型DP】:

解一个题的时候可以通过向左树要信息,向右树要信息;

【不适用二叉树套路的题目】:

【整棵树所有值的中位数】:

//排完序之后的中位数。——这种类型的题目就无法通过《二叉树套路》来解;

中位数信息是要结合所有情况来看的;

  • 《@@73_2》

//中位数这种固定套路的可能不会在面试过程中出现~~~

【无法用套路解的】:

这个套路不能解的题目,往往非常的麻烦 ~

  • 不适用这个套路的题目,一般也不会考,因为它区分度很低~

【 最低公共祖先 】:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xccnACQn-1663994025826)(/Users/yuguangyao/Library/Application Support/typora-user-images/image-20220822152830950.png)]

  • 《73_3》

  • 神一样的递归代码
    //——————下面是:比较难理解的代码~~~
    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;
    }

【 lowestAncestor中o1、o2 的所有可能 】:

  • 《@@74_4》

[一定返回null]:

如果一个树上既没有O1,又没有O2 , 那么它是一定会返回null的~

【后继节点】:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EZG7FHeT-1663994025826)(/Users/yuguangyao/Library/Application Support/typora-user-images/image-20220823202441290.png)]

【概念】:

中序遍历中一个节点的下一个节点。

【经典后继节点例子】:

  • 《@@76_5》

中序遍历结果:DBEAFCG

//所以我们说B的后继节点是E;

//E的后继节点是A。

//A的后继节点是F。

//G的后继节点是空。

【前驱节点】:

中序遍历中一个节点的前一个节点。

【父指针】:

经典二叉树中只有指左孩、右孩的指针,该题是有parent( 指向父节点 )指针的;

//每个parent指针都是好的,确实能正确地指向自己的父亲。

【快一些找到后继节点】:

经典二叉树需要先中序遍历来得到一个list集合。

  • 代价很高:

要遍历所有的节点来得到一个List ~。//这种方式的复杂度是 O(N)

【优化后的复杂度】:

X -----( 有K步 )-----> Y //前提是得有parent指针;

  • O(K)

X节点到其后继节点Y之间有K步 , 则找到X节点的时间复杂度就是O( K );

//一个节点找后继,理论上是可以只走有限距离的。

【如何在结构上来寻找后继节点】:

原来可以偷懒(先中序遍历得到一个List集合。)

【 后继节点规律 】:
  • 《@@76_6》

【 特殊节点 】:

二叉树中最后一个节点是没有后继节点的,因为它所有的父亲都发现自己不是左分支( 一直到根节点 )。

//最后一个节点的后继节点是——Null .

【 只有最后的节点才会发现 】:

我父亲的节点都走到空了 , 也没发现自己是父亲的左孩子。

【二叉树的序列化/反序列化】:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EvZxk8tx-1663994025826)(/Users/yuguangyao/Library/Application Support/typora-user-images/image-20220823224419183.png)]

  • 树—>字符串

【反序列化】:

字符串要能够对应出唯一的结构来~

//一颗树的结构和值都能对应成一个唯一的字符串;

结构和字符串是一一对应的关系,不是多对多的关系。

【两棵树序列化的结果】:

//加下划线是表示一个值的结束;

//用#来表示空;

  • 《@@77_7》

【先序方式反序列化】:

  • 头左右

  • 《@@77_8》

//先建立头节点,然后建立头节点的左子树,左子树建完了———再建右子树~~~!!!

【微软原题(折纸)】:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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
  • 给你对折的次数,让你从上到下,打印折痕的凹凸方向。

【折痕规律】:

每一条折痕的上下都会出现一个新折痕,上凹下凸;

【二叉树中序遍历】:

你想打印折痕的方向,就是对下图这棵二叉树作中序遍历:

  • 《@@78_9》(折痕树)

//总树的头节点为凹折痕;

//每一颗左子树的头节点都是凹折痕;

//每一颗右子树的头节点都是凸折痕;

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值