IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 《经典算法题》二叉树基础(二) -> 正文阅读

[数据结构与算法]《经典算法题》二叉树基础(二)

前言:

二叉树的题目绝大多数都可以利用递归来解决,熟练掌握二叉树的前中后序遍历以及层序遍历是能快速解决二叉树题目的基础。


目录

前言:

一:判断完全二叉树

1.1:思路

1.2:代码

?1.3代码:

二:二叉树的最大宽度

2.1:思路

2.2: 代码1

2.2:代码2

三:二叉树的最大距离

3.1:思路

3.2:代码



一:判断完全二叉树

💡:判断一颗二叉树是完全二叉树.(拓展题非力扣)

1.1:思路

🔑:完全二叉树的定义:除最后一层外,其它层为全满结构,且最后一层的节点全部集中在

左边(即最后一层是从左到右渐满的结构)。

?

?解法一:

? ? ?判断完全二叉树的条件:

? ? ?(1):存在节点有右孩子但无左孩子,则一定不是完全二叉树

? ? ? ?(2):在层序遍历中,遇到叶子节点后,后边遇到的所有节点均是叶子节点,如上图

F节点是叶子节点,则G,H,I,J全是叶子节点。如果遇到了叶子节点,后面还有非叶子节点,则一定

不是完全二叉树。

1.2:代码

    //给你一个二叉树,请判断其是否为完全二叉树
    //判断规则两条
    //1:如果遇到有右孩子,无左孩子的一定不是完全二叉树
    //2:如果遇到了左右不双全的节点(即:没有左孩子和右孩子的节点),则之后的所有点,都是叶子节点
   public static class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;
        public  TreeNode(int val){
            this.val=val;
        }
    }
    public static boolean isCBT(TreeNode root){
        //默认空树是完全二叉树
        if(root==null){
            return true;
        }
        //基于宽度优先遍历的判断规则
        Queue<TreeNode> queue=new LinkedList<>();
        TreeNode left=null;
        TreeNode right=null;
        boolean isMeet=false;//是否遇到了叶子节点
        queue.add(root);
        while(!queue.isEmpty()){
            TreeNode cur=queue.poll();
            left=cur.left;
            right=cur.right;
            if((right!=null&&left==null)||(isMeet&&left!=null)){
                return false;
            }
            //设置好isMeet
            isMeet=left==null;
            if(left!=null){
                queue.add(left);
            }
            if(right!=null){
                queue.add(right);
            }
        }
        return true;
    }

解法二:

💡:回顾一下完全二叉树的定义,除最后一层外,其它层属于全满结构,最后一层的节点全部集中在左侧,因此我们可以分类讨论最后一层节点的情况。

情况一:A的左子树是完全二叉树,A的右子树是满二叉树,且左子树高度=右子树高度+1

?情况二:A的左子树是满二叉树,A的右子树是完全二叉树,且左子树高度=右子树高度+1

?情况三:A的左子树是满二叉树,A的右子树是完全二叉树,且左子树高度=右子树高度

?情况四:A的左子树是满二叉树,A的右子树是满二叉树,且左子树高度=右子树高度

?1.3代码:

    public static class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int val){
            this.val=val;
        }
    }
    //完全二叉树的定义:除最后一层之外其它层为全满
    //最后一层为从左到右渐满的结构
    public static class Info{
        public boolean isFBT;
        public boolean isCBT;
        public int height;
        public Info(boolean a,boolean b,int c){
            isFBT=a;
            isCBT=b;
            height=c;
        }
    }
    public static boolean isCBT(TreeNode root ){
        return process(root).isCBT;
    }
    public static Info process(TreeNode node){
        //base case
        if(node==null){
            return new Info(true,true,0);
        }
        Info leftInfo=process(node.left);
        Info rightInfo=process(node.right);
        //高度为左子树高度和右子树高度的较大者+1
        int height=Math.max(leftInfo.height, rightInfo.height)+1;
        //满二叉树的条件:左子树是满二叉树,右子树是满二叉树,左子树高度=右子树高度
        boolean isFBT= leftInfo.isFBT&& rightInfo.isFBT&&leftInfo.height== rightInfo.height;
        boolean isCBT=false;
        if(isFBT){
            isCBT=true;
        }
        else if(leftInfo.isCBT&& rightInfo.isFBT&&(leftInfo.height== rightInfo.height+1)){
            isCBT=true;
        }
        else if(leftInfo.isFBT&& rightInfo.isFBT&&(leftInfo.height== rightInfo.height+1)){
            isCBT=true;
        }
        else if(leftInfo.isFBT&& rightInfo.isCBT&&(leftInfo.height== rightInfo.height)){
            isCBT=true;
        }
        return new Info(isFBT,isCBT,height);
    }

二:二叉树的最大宽度

题目:求二叉树的最大宽度,即节点最多的层的节点数目

2.1:思路

💡:利用层序遍历,统计每一层的节点数目

2.2: 代码1

    //求二叉树所有层中,节点个数最多层的节点数
    //二叉树的bfs的应用 下面写三种解法
    public static class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int val){
            this.val=val;
        }
    }
    public static int maxWidth(TreeNode root){
        if(root==null){
            return 0;
        }
        Queue<TreeNode> queue=new LinkedList<>();
        queue.add(root);
        //层序遍历会在遍历上一层的时候将下一层逐渐加入队列中
        //这个过程队列中既有上一层节点也有下一层节点
        //当上一层彻底遍历结束的时候,队列中就只有下一层的节点
        int maxWidth=0;
        while(!queue.isEmpty()){
            int size=queue.size();
            maxWidth=Math.max(maxWidth,size);
            for(int i=0;i<size;i++){
                TreeNode cur=queue.poll();
                if(cur.left!=null){
                    queue.add(cur.left);
                }
                if(cur.right!=null){
                    queue.add(cur.right);
                }
            }
        }
        return maxWidth;
    }

2.2:代码2

💡:我们可以用变量来标记当前层的最后节点,这样我们遍历的时候就能区分每一层。

    //方法二:在统计每一层的时候,刷新每一层的结束位置
    public static int maxWidth2(TreeNode head){
        if(head==null){
            return 0;
        }
        Queue<TreeNode> queue=new LinkedList<>();
        queue.add(head);
        int maxWidth=0;
        TreeNode curEnd=head;//当前层的最后节点
        //在遍历当前层的时候,动态刷新出下一层的最后节点
        //当当前遍历到的节点是当前层的最后节点时,做一次总结
        TreeNode nextEnd=null;
        int curLevelNodes=0;
        while(!queue.isEmpty()){
            TreeNode cur=queue.poll();
            curLevelNodes++;
            if(cur.left!=null){
                nextEnd=cur.left;
                queue.add(cur.left);
            }
            if(cur.right!=null){
                nextEnd=cur.right;
                queue.add(cur.right);
            }
            //检查一次
            if(cur==curEnd){
                maxWidth=Math.max(maxWidth,curLevelNodes);
                curLevelNodes=0;
                curEnd=nextEnd;
            }
        }
        return maxWidth;
    }

三:二叉树的最大距离

题目:二叉树中任意两节点间都会有一个距离,该距离就是由一个节点到另一个节点的路径上的节点个数。

3.1:思路

💡:在以x为头的二叉树中,有三种情况

1) 最大距离在x的左子树上

2)最大距离在x的右子树上

3)最大距离经过x节点,是左子树的高度+右子树的高度+1

以x为头整颗树的最大高度是这三种情况的最大值

3.2:代码

    public static class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int val){
            this.val=val;
        }
    }
    public static class Info{
        public int maxDistance;
        public int height;
        public Info(int maxDistance,int height){
            this.maxDistance=maxDistance;
            this.height=height;
        }
    }
    public static Info process(TreeNode node){
        //base case
        if(node==null){
            return new Info(0,0);
        }
        Info leftInfo=process(node.left);
        Info rightInfo=process(node.right);
        int height=Math.max(leftInfo.height,rightInfo.height)+1;
        int maxDistance=Math.max(
                Math.max(leftInfo.maxDistance, rightInfo.maxDistance),
                rightInfo.height+ rightInfo.height+1
        );
        return new Info(maxDistance,height);
    }
    public static int maxDistance(TreeNode root){
        return process(root).maxDistance;
    }

由于本人水平十分有限,若有错误请即使告知!如果有帮助别忘了

点赞👍? ? ? ? ?收藏?? ? 关注?

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-02-05 21:57:54  更:2022-02-05 21:58:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 17:48:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码