实现二叉树的基本操作与OJ练习

目录

1.二叉树的基本操作

1.1二叉树基本操作完整代码 

 1.2检测value值是否存在

1.3层序遍历

1.4判断一棵树是不是完全二叉树 

 2.OJ练习

2.1平衡二叉树

2.2对称二叉树 

2.3二叉树遍历 


1.二叉树的基本操作

1.1二叉树基本操作完整代码 

public class BinaryTree {
    static class TreeNode{
        public char val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(char val) {
            this.val = val;
        }
    }
    //使用穷举,实现一棵树
    public TreeNode creatTree() {
        TreeNode A = new TreeNode('A');
        TreeNode B = new TreeNode('B');
        TreeNode C = new TreeNode('C');
        TreeNode D = new TreeNode('D');
        TreeNode E = new TreeNode('E');
        TreeNode F = new TreeNode('F');
        TreeNode G = new TreeNode('G');
        TreeNode H = new TreeNode('H');
        A.left = B;
        A.right = C;
        B.left = D;
        B.right = E;
        C.left = F;
        C.right = G;
        E.right = H;
        return A;
    }
    // 前序遍历  根 左子树 右子树
     public void preOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        System.out.print(root.val + " ");
        preOrder(root.left);
        preOrder(root.right);
    }
    // 中序遍历 左 根 右
    public void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        System.out.print(root.val + " ");
        inOrder(root.right);
    }
    // 后序遍历 左 右 根
    public void postOrder(TreeNode root){
        if (root == null) {
            return;
        }
        inOrder(root.left);
        inOrder(root.right);
        System.out.print(root.val + " ");
    }
    // 获取树中节点的个数
    public int sizeCount;
    public void size(TreeNode root){
        if(root == null) {
            return;
        }
        sizeCount++;
        size(root.left);
        size((root.right));
    }
    //子问题
    public int  size2(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return size2(root.left) + size2(root.right) + 1;
    }
    // 获取叶子节点的个数
    public int leafCount;
    //遍历求解
    public void getLeafNodeCount(TreeNode root) {
        if (root == null) {
            return;
        }
        if (root.left == null && root.right == null){
            leafCount++;
        }
        getLeafNodeCount(root.left);
        getLeafNodeCount(root.right);
    }
    // 子问题思路-求叶子结点个数
    public int getLeafNodeCount2(TreeNode root){
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null) {
            return 1;
        }
        //左子树的叶子节点+右子树的叶子节点
        return getLeafNodeCount2(root.left) +
                getLeafNodeCount2(root.right);
    }
    // 获取第K层节点的个数
    public int getKLevelNodeCount(TreeNode root,int k) {
        if (root == null) {
            return 0;
        }
        if (k == 1) {
            return 1;
        }
        return getKLevelNodeCount(root.left,k-1) +
                getKLevelNodeCount(root.right,k-1);
    }
    // 获取二叉树的高度
    public int getHeight(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftHeight = getHeight(root.left);
        int rightHeight = getHeight(root.right);
        return Math.max(leftHeight,rightHeight) + 1;
    }
    // 检测值为value的元素是否存在
    public TreeNode find(TreeNode root, int val) {
        if (root == null) {
            return null;
        }
        if (root.val == val) {
            return root;
        }
        TreeNode leftVal = find(root.left,val);
        if (leftVal != null) {
            return leftVal;
        }
        TreeNode rightVal =find(root.right,val);
        if (rightVal != null) {
            return rightVal;
        }
        //左、右子树都没有
        return null;
    }
    //层序遍历
    public void levelOrder(TreeNode root){
        if (root == null) {
            return;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode cur = queue.poll();
            System.out.print(cur.val+" ");
            if(cur.left != null) {
                queue.offer(cur.left);
            }
            if (cur.right != null) {
                queue.offer(cur.right);
            }
        }
    }
    //判断一棵树是不是完全二叉树
   public boolean isCompleteTree(TreeNode root){
        if(root == null) {
            return true;
        }
       Queue<TreeNode> queue = new LinkedList<>();
       queue.offer(root);
       while (!queue.isEmpty()) {
           TreeNode cur = queue.poll();
           if (cur != null) {
               queue.offer(cur.left);
               queue.offer(cur.right);
           } else {
               break;
           }
       }
       //走到这里两种情况 1.队列为空 2.遇到break
       while (!queue.isEmpty()) {
           TreeNode cur = queue.peek();
           if (cur != null) {
               queue.poll();
           } else {
               return false;
           }
       }
        return true;
   }
}

 1.2检测value值是否存在

题解

1.3层序遍历

题解:

层序遍历:就是从上到下,从左到右,依次遍历。前序、中序、后序本质上都是从上到下。

所以,就是要解决从左到右。

可以引入队列解决(先进先出),如果不是空树,先把根节点放到队列里,此时队列不为空,当该节点出队是,用cur记录,不为空并把该节点的左、右节点放进队列。

1.4判断一棵树是不是完全二叉树 

题解:

也是引入队列解决,当cur不为空把该节点的左、右节点放进队列;否则跳出循环。

在遍历队列,是否都为null.

 2.OJ练习

2.1平衡二叉树

题解:

是不是一颗平衡二叉树,当前根节点的左右子树的高度差的绝对值<=1&&根左子树平衡&&根右子树平衡。

如下代码:就会发现求节点3的高度,把每个节点都求了一遍。 求节点9的高度时,也把每个节点都求了一遍。就会有很高度重复求,maxDepth有N个节点,最坏时间复杂度:N*N=N^2.

    public boolean isBalanced(TreeNode root) {
        if(root == null) {
            return true;
        }
        int leftHeight = maxDepth(root.left);
        int rightHeight = maxDepth(root.right);
        return Math.abs(leftHeight - rightHeight) <= 1 &&
                isBalanced(root.left)&&isBalanced(root.right);

    }
   public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftHeight = maxDepth(root.left);
        int rightHeight = maxDepth(root.right);
        return Math.max(leftHeight, rightHeight) + 1;
    }

 省略掉重复计算的高度!

    public boolean isBalanced2(TreeNode root) {
        if(root == null) {
            return true;
        }

        return maxDepth(root) >= 0;

    }
    public int maxDepth2(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftHeight = maxDepth2(root.left);
        if(leftHeight < 0) {
            return -1;
        }
        int rightHeight = maxDepth2(root.right);
        if(leftHeight >= 0 && rightHeight >= 0
                && Math.abs(leftHeight - rightHeight) <= 1){
            return Math.max(leftHeight,rightHeight) + 1;
        } else {
            return -1;
        }
    }

2.2对称二叉树 

     题目描述:给你一个二叉树的根节点 root , 检查它是否轴对称。 

题解:

    public boolean isSymmetric(TreeNode root) {
        if(root == null) {
            return true;
        }
        return isSameTree2(root.left,root.right);

    }
    public boolean isSameTree2(TreeNode lefTree,TreeNode rightTree){
        if(lefTree == null && rightTree != null || lefTree != null && rightTree == null) {
            return false;
        }
        if(lefTree == null && rightTree == null) {
            return true;
        }
        if(lefTree.val != rightTree.val) {
            return false;
        }
        return isSameTree2(lefTree.left,rightTree.right)
                &&isSameTree2(lefTree.right,rightTree.left);
    }

2.3二叉树遍历 

题目描述:编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。

题解: 

  遍历这个字符串,根据前序遍历的方式,创建二叉树

   class TreeNode {
        char val;
        TreeNode left;
        TreeNode right;

        public TreeNode(char val) {
            this.val = val;
        }
    }

    // 注意类名必须为 Main, 不要有任何 package xxx 信息
    public class Main {
        public static int i = 0;
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            // 注意 hasNext 和 hasNextLine 的区别
            while (in.hasNextLine()) { // 注意 while 处理多个 case
                String str = in.nextLine();

                TreeNode root = creatTree(str);

                inOrder(root);
            }
        }
        public static TreeNode creatTree(String str) {
            //1.遍历字符串
            //2.创建二叉树
            TreeNode root = null;
            if(str.charAt(i)!= '#') {
                root = new TreeNode(str.charAt(i));
                i++;
                root.left = creatTree(str);
                root.right = creatTree(str);

            } else{
                i++;
            }
            //返回根节点
            return root;
        }
        public static void inOrder(TreeNode root) {
            if(root == null) {
                return;
            }
            inOrder(root.left);
            System.out.print(root.val+" ");
            inOrder(root.right);
        }
    }

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/279885.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Unity】【FBX】如何将FBX模型导入Unity

【背景】 网上能够找到不少不错的FBX模型资源&#xff0c;大大加速游戏开发时间。如何将这些FBX导入Unity呢&#xff1f; 【步骤】 打开Unity项目文件&#xff0c;进入场景。 点击Projects面板&#xff0c;右键选择Import New Assets 选中FBX文件后导入。Assets文件夹中就会…

Python 内置高阶函数练习(Leetcode500.键盘行)

Python 内置高阶函数练习&#xff08;Leetcode500.键盘行&#xff09; 【一】试题 &#xff08;1&#xff09;地址&#xff1a; 500. 键盘行 - 力扣&#xff08;LeetCode&#xff09; &#xff08;2&#xff09;题目 给你一个字符串数组 words &#xff0c;只返回可以使用在…

东方甄选小作文事件最大的赢家是谁? 董宇辉还是俞敏洪

有人说东方甄选小作文事件没有赢家&#xff0c;小马识途营销顾问认为小作文事件最终也没有输家。就公司来讲&#xff0c;有机会培养更多优秀主播&#xff0c;未来发展更健康了&#xff1b;就俞老师来讲&#xff0c;是把宇辉的薪酬和职位提高了&#xff0c;这些也是宇辉本来就应…

3D视觉-结构光测量-线结构光测量

概述 线结构光测量中&#xff0c;由激光器射出的激光光束透过柱面透镜扩束&#xff0c;再经过准直&#xff0c;产生一束片状光。这片光束像刀刃一样横切在待测物体表面&#xff0c;因此线结构光法又被成为光切法。线结构光测量常采用二维面阵 CCD 作为接受器件&#xff0c;因此…

模型 安索夫矩阵

本系列文章 主要是 分享模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。产品市场战略。 1 安索夫矩阵的应用 1.1 江小白的多样化经营策略 使用安索夫矩阵来分析江小白市场战略。具体如下&#xff1a; 根据安索夫矩阵&#xff0c;江小白的现有产品是其白酒产品&…

【23.12.30期--Spring篇】Spring的AOP介绍(详解)

Spring的AOP介绍 ✔️简述✔️扩展知识✔️AOP是如何实现的 ✔️简述 AOP(Aspect-Oriented Programming)&#xff0c;即面向切面编程&#xff0c;用人话说就是把公共的逻辑抽出来&#xff0c;让开发者可以更专注于业务逻辑开发。 和IOC-样&#xff0c;AOP也指的是一种思想。AOP…

Android APK未签名提醒

最近新建了一个项目&#xff0c;在build.gradle中配置好了签名&#xff0c;在执行打包的时候打出的包显示已签名&#xff0c;但是在上传市场的时候提示未签名。于是排查了好久&#xff0c;发现在build.gradle中配置的minsdk 24&#xff0c;会导致不使用V1签名&#xff0c;于是我…

【洛谷学习自留】p7621 超市购物

2023/12/29 解题思路&#xff1a; 简单的计算&#xff0c;难度主要集中在格式化输出和四舍五入的问题上。 1.建立一个计数器&#xff0c;for循环遍历单价和数量的乘积&#xff0c;存入计数器。 2.计算计数器的最终值乘以0.85h后的结果&#xff0c;为了保证四舍五入正确&…

小程序入门-登录+首页

正常新建一个登录页面 创建首页和TatBar&#xff0c;实现登录后底部出现两个按钮 代码 "pages": ["pages/login/index","pages/index/index","pages/logs/logs" ],"tabBar": {"list": [{"pagePath"…

数模学习day05-插值算法

插值算法有什么作用呢&#xff1f; 答&#xff1a;数模比赛中&#xff0c;常常需要根据已知的函数点进行数据、模型的处理和分析&#xff0c;而有时候现有的数据是极少的&#xff0c;不足以支撑分析的进行&#xff0c;这时就需要使用一些数学的方法&#xff0c;“模拟产生”一些…

Linux文件fd剖析

学习之前&#xff0c;首先要认识什么是文件&#xff1f; 空文件也是要在内存中占据空间的&#xff0c;因为它还有属性数据。文件 属性 内容文件操作 对内容 对属性 或者对内容和属性的操作标定一个文件的时候&#xff0c;必须使用&#xff1a;路径文件名&#xff0c;文件具…

Spring-4-代理

前面提到过&#xff0c;在Spring中有两种类型的代理&#xff1a;使用JDK Proxy类创建的JDK代理以及使用CGLIB Enhancer类创建的基于CGLIB的代理。 你可能想知道这两种代理之间有什么区别&#xff0c;以及为什么 Spring需要两种代理类型。 在本节中&#xff0c;将详细研究代理…

Android 理解Context

文章目录 Android 理解ContextContext是什么Activity能直接new吗&#xff1f; Context结构和源码一个程序有几个ContextContext的作用Context作用域获取ContextgetApplication()和getApplicationContext()区别Context引起的内存泄露错误的单例模式View持有Activity应用正确使用…

安全配置审计概念、应用场景、常用基线及扫描工具

软件安装完成后都会有默认的配置&#xff0c;但默认配置仅保证了服务正常运行&#xff0c;却很少考虑到安全防护问题&#xff0c;攻击者往往利用这些默认配置产生的脆弱点发起攻击。虽然安全人员已经意识到正确配置软件的重要性&#xff0c;但面对复杂的业务系统和网络结构、网…

儿童学python语言能做什么,儿童学python哪个机构好

这篇文章主要介绍了儿童学python哪个线上机构好&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 少儿编程python 文章目录 前言 CSP-J与CSP-S少儿编程证书含金量排名&#xff0…

SSH -L:安全、便捷、无边界的网络通行证

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 SSH -L&#xff1a;安全、便捷、无边界的网络通行证 前言1. SSH -L基础概念SSH -L 的基本语法&#xff1a;端口转发的原理和作用&#xff1a; 2. SSH -L的基本用法远程访问本地示例&#xff1a;访问本…

git 常用操作合集

✨专栏介绍 在当今数字化时代&#xff0c;Web应用程序已经成为了人们生活和工作中不可或缺的一部分。而要构建出令人印象深刻且功能强大的Web应用程序&#xff0c;就需要掌握一系列前端技术。前端技术涵盖了HTML、CSS和JavaScript等核心技术&#xff0c;以及各种框架、库和工具…

贴片电容和薄膜电容的区别

一、贴片电容和薄膜电容的定义 贴片电容是指体积较小、形状像片的电容器&#xff0c;广泛应用于电路板和电子元器件中。薄膜电容是指以金属膜作为电极的电容器&#xff0c;广泛应用于高频和精密电路中。 二、贴片电容和薄膜电容的应用 贴片电容广泛应用于数码产品、无线通信…

JavaScript中实现页面跳转的几种常用方法

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍在JavaScript中实现页面跳转的几种常用方法以及部分理论知识 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主收将持续更新学习记录获&#xff0c;友友们有任何问题…

Linux文件的扩展属性 attr cap

文件属性 Linux文件属性分为常规属性与扩展属性&#xff0c;其中扩展属性有两种&#xff1a;attr与xattr. 一般常规的文件属性由stat API 读取&#xff0c;一般是三种权限&#xff0c;ower, group&#xff0c;时间等。 扩展属性attr 用户态API ioctl(fd, FS_IOC32_SETFLAGS…