当前位置: 首页 > news >正文

硅基计划3.0 学习总结 肆 二叉树 初版

在这里插入图片描述


文章目录

    • 一、树与性质
      • 1. 二叉树初识
      • 2. 树的表示
      • 3. 二叉树性质
    • 二、模拟实现二叉树
      • 1. 创建二叉树
      • 2.遍历
      • 3. 求节点个数
      • 4. 求叶子节点
      • 5. 求第K层节点个数
      • 6. 获取二叉树的高度(深度)
      • 7. 检测指定值是否存在于二叉树中


一、树与性质

1. 二叉树初识

二叉树指的是不存在>=2度数(子节点个数)的节点,分为左右子树,但是二叉树也有可能是空树

  • 完全二叉树:节点编号和节点一一对应,而且如果节点度数是偶数,不存在度为1的节点,如果是偶数,则一定存在一个度为1的节点,如下图所示
    image-20250727145324800

  • 满二叉树:每个节点除了最后一层以外的节点度数都为2,起始就是完全二叉树的特殊情况

2. 树的表示

树可以有多种表示方法,有双亲表示、孩子表示、孩子兄弟等,对于树的定义不过多细讲了

class Node{int value;Node firstChild;Node NextBrother;
}

image-20250727144311995

3. 二叉树性质

  1. 如果规定第一层的层数下标是一(意思就是不是用数组那种从零下标开始的叫法),那么第L层的最多有2k−12^k-12k1个节点
  2. 如果规定第一层的深度下标是一,那么深度为K的树节点总共有2k−12^k -12k1个节点
  3. 度为1的节点总比度为0的节点少一个

度数之和是度数为0的节点之和+度为1的节点之和+度为2的节点之和
而且边数比节点数少一个,利用这个性质,我们可以得到这个推论

  1. 具有n个节点的完全二叉树的深度为log⁡2(n+1)\log_2 (n+1)log2(n+1),结果向上取整(比如5.2–>6,5.8–>6)
  2. 含有n个节点的完全二叉树,如果i=0,那么它就是根节点,否则如果下标i>0,那么它的双亲下标就是(i-1)/2;同理如果2i+1<n,它的左子树(左孩子)下标是2i+1,否则不存在;同理如果2i+2>n,它的右子树(右孩子)下标是2i+2,否则不存在
    image-20250727151438449

二、模拟实现二叉树

二叉树的表示常用的是孩子表示法(一个节点的左右两个子节点)和孩子双亲表示法(除了左右两个子节点还包括自己)
接下来我们模拟实现最常用的孩子表示法

1. 创建二叉树

public class BinaryTree {static class TreeNode{int value;TreeNode left;//左孩子TreeNode right;//右孩子public TreeNode(int value) {this.value = value;}}public TreeNode creatNode(){TreeNode t1 = new TreeNode(15);TreeNode t2 = new TreeNode(22);TreeNode t3 = new TreeNode(34);TreeNode t4 = new TreeNode(56);TreeNode t5 = new TreeNode(77);TreeNode t6 = new TreeNode(99);//手动连接//左子树t1.left = t2;t1.right = t3;t2.left = t4;t2.right = t5;//右子树t3.left = t6;//返回头节点return t1;}//一些操作方法
}//测试类中
public class Test {BinaryTree binaryTree = new BinaryTree();BinaryTree.TreeNode root = binaryTree.creatNode();
}

2.遍历

image-20250727154448574
分为前序——根节点左孩子节点右孩子节点,中序——左跟右,后序——左右根,区别只是遍历的顺序不一样,他们的时间空间复杂度都是O(n)

    //前序遍历public void preOrder(TreeNode root){if(root == null){return;}System.out.print(root.value+" ");preOrder(root.left);preOrder(root.right);}//中序遍历public void inOrder(TreeNode root){if(root == null){return;}inOrder(root.left);System.out.print(root.value+" ");inOrder(root.right);}//后序遍历public void pastOrder(TreeNode root){if(root == null){return;}pastOrder(root.left);pastOrder(root.right);System.out.print((root.value + " "));}//测试//前序遍历binaryTree.preOrder(root);System.out.println();//中序遍历binaryTree.inOrder(root);//后序遍历System.out.println();binaryTree.pastOrder(root);

这里我就拿前序遍历举例子
image-20250727161000360

3. 求节点个数

我们思路就是利用计数器,或者是子问题思路——左子树节点个数+有子树节点个数,他们的时间空间复杂度都是O(n)

ublic int count = 0;//计数器法则public void size(TreeNode root){if(root == null){return;}count++;size(root.left);size(root.right);}//子问题法则public int sizePlus(TreeNode root){if(root == null){return 0;}return sizePlus(root.left)+sizePlus(root.right)+1;}

4. 求叶子节点

我们的思路就是如果遇到了叶子节点就++,即当前节点的左右孩子节点都是空,时间空间复杂度都是O(n)

public int getLeafNodeCount(TreeNode root){if(root == null){return 0;}if(root.left == null && root.right == null){return 1;}return getLeafNodeCount(root.left)+getLeafNodeCount(root.right);}

5. 求第K层节点个数

我们思路就是第K层是左子树的K-1层+右子树的K-1层
我们让K一直减减,直到K=1的时候,时间空间复杂度都是O(n)

//求第K层节点个数public int getLevelCount(TreeNode root,int k){if(root == null){return 0;}if(k == 1){return 1;}return getLevelCount(root.left,k-1)+getLevelCount(root.right,k-1);}

6. 获取二叉树的高度(深度)

我们思路就是左右两个子树求出深度,谁的值比较大就取谁,最后再加上一(根节点),时间复杂度是O(n),空间复杂度是O(logN)

//求二叉树深度public int getHeight(TreeNode root){if(root == null){return 0;}return Math.max(getHeight(root.left),getHeight(root.right))+1;}

7. 检测指定值是否存在于二叉树中

我们的思路就是先判断根节点是不是我们要找的值,不是就递归,如果左子树没有,就去判断右子树,时间复杂度O(n),空间复杂度O(logN)

//检测值是否存在public TreeNode find(TreeNode root,int value){if(root == null){//终止情况return null;}if(root.value == value){//检测根节点情况return root;}TreeNode ret = find(root.left,value);//检查左子树if(ret != null){return ret;//找到了直接返回,下面语句不用进行了}ret = find(root.right,value);//左子树找不到,找右子树if(ret != null){return ret;//找到了直接返回}return null;//找不到语句到这里}

文章错误不可避免,期待您的指正,我们共同进步

Git码云仓库链接

END
http://www.xdnf.cn/news/1200817.html

相关文章:

  • 疯狂星期四文案网第21天运营日记
  • 剑指offer第2版:双指针+排序+分治+滑动窗口
  • QT6 源,七章对话框与多窗体(17)用于辅助多文档 MDI 窗体设计 QMdiArea 的类 QMdiSubWindow:
  • MySQL 8.4 Windows 版安装记录与步骤参考
  • 《频率之光:群星之我》
  • mmap的调用层级与内核态陷入全过程
  • 依赖倒置原则 Dependency Inversion Principle - DIP
  • 不坑盒子突然不见了怎么办?
  • VILA系列论文解读
  • 详细解释一个ros的CMakeLists.txt文件
  • AI大模型前沿:Muyan-TTS开源零样本语音合成技术解析
  • 自然语言处理NLP (1)
  • 【I】题目解析
  • vmware虚拟机中显示“网络电缆被拔出“的解决方法
  • rust-包和箱子
  • RHEL9 网络配置入门:IP 显示、主机名修改与配置文件解析
  • 电动汽车转向系统及其工作原理
  • 8.c语言指针
  • Web开发系列-第0章 Web介绍
  • SQL注入SQLi-LABS 靶场less21-25详细通关攻略
  • Ubuntu普通用户环境异常问题
  • 数学建模——灰色关联分析
  • 三、构建一个Agent
  • OpenCv中的 KNN 算法实现手写数字的识别
  • 消息队列MQ常见问题和解决方案
  • Java面试全攻略:Spring生态与微服务架构实战
  • 新手开发 App,容易陷入哪些误区?
  • Android:Reverse 实战 part 2 番外 IDA python
  • SignalR 全解析:核心原理、适用场景与 Vue + .NET Core 实战
  • [电网备考]计算机组成与原理