【Java数据结构】二叉树详解(二)

news2024/11/15 11:38:19

🔒文章目录:

1.❤️❤️前言~🥳🎉🎉🎉

2. 二叉树的模拟——正文

2.1获取树中节点的个数 

2.2获取叶子节点的个数

2.3获取第K层节点的个数

2.4获取二叉树的高度  

2.5 检测值为value的元素是否存在

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

2.7遍历 

2.7.1先序遍历

2.7.2中序遍历 

2.7.3后序遍历

2.7.4层序遍历 

3.二叉树的模拟——使用

4.特别说明 

5.总结


1.❤️❤️前言~🥳🎉🎉🎉

Hello, Hello~ 亲爱的朋友们👋👋,这里是E绵绵呀✍️✍️。

如果你喜欢这篇文章,请别吝啬你的点赞❤️❤️和收藏📖📖。如果你对我的内容感兴趣,记得关注我👀👀以便不错过每一篇精彩。

当然,如果在阅读中发现任何问题或疑问,我非常欢迎你在评论区留言指正🗨️🗨️。让我们共同努力,一起进步!

加油,一起CHIN UP!💪💪

🔗个人主页:E绵绵的博客
📚所属专栏:

1. JAVA知识点专栏

        深入探索JAVA的核心概念与技术细节

2.JAVA题目练习

        实战演练,巩固JAVA编程技能

3.c语言知识点专栏

        揭示c语言的底层逻辑与高级特性

4.c语言题目练习

        挑战自我,提升c语言编程能力

📘 持续更新中,敬请期待❤️❤️

2. 二叉树的模拟——正文

因为我们在上篇文章中已经对二叉树的模拟进行了一个前置的了解,还对二叉树的基础:遍历做了一个深度了解,那么现在我们就可以开始二叉树模拟的正文了,正文中我们将会模拟二叉树的基本方法和二叉树的四种遍历方式(前序,中序,后序,层序)。


二叉树的基本方法如下:

因为在二叉树模拟的前置说明中我们已经创建好了一个二叉树,所以我们以它为操作对象去执行我们模拟的基本方法和四种遍历方式。


2.1获取树中节点的个数 

我们采用递归的方式去实现。具体如下:

定义该函数的名称为 size,它接受一个参数 root,表示以该节点为根的二叉树。

首先定义一个变量 size,用于记录二叉树节点的个数,并初始化为 0。

然后判断 root 是否为 null,如果为 null,说明当前节点为空,直接返回 0。

否则,将 size 加 1,表示当前节点不为空,计入节点个数。

接着,对左子树和右子树进行递归调用 size 函数,分别计算左右子树中节点的个数。

最后将左右子树的节点个数加起来,并加上当前节点,即为整个二叉树的节点个数,返回 size。


int size(BTNode root) {
        int size = 0;
        if (root == null)
            return 0;
        size++;
        size = size + size(root.left);
        size = size + size(root.right);
        return size;
    }

 2.2获取叶子节点的个数

注意:度为0的结点称为叶子结点。

我们设计一个函数名为 getLeafNodeCount,输入参数是二叉树的根节点 root,返回值是整数类型,表示二叉树中叶子节点的数量。

函数的实现思路是:如果二叉树为空,那么叶子节点数量为 0;否则,如果当前节点是叶子节点,则叶子节点数量加 1;接着递归地计算左子树和右子树中叶子节点的数量,并将它们相加作为最终的结果返回。

具体而言,该代码中首先定义了一个变量 size 并初始化为 0。然后通过判断二叉树的根节点是否为空,来处理递归结束的情况。如果当前节点是叶子节点,则将 size 的值加 1;之后则递归地计算左右子树中叶子节点的数量,并将它们累加到 size 中。最后将 size 作为函数的返回值。


 int getLeafNodeCount(BTNode root) {
        int size = 0;
        if (root == null)
            return 0;
        if ((root.left == null) && (root.right == null))
            size++;
        size = size + getLeafNodeCount(root.left);
        size = size + getLeafNodeCount(root.right);
        return size;
    }

 2.3获取第K层节点的个数

具体分析如下:

首先,定义一个函数getKLevelNodeCount,该函数需要传入两个参数:一个是二叉树的根节点root,另一个是需要统计节点个数的层数k。

接着,该函数定义了一个整型变量size并将其初始化为0。

然后,通过对root节点进行判断,若root为空,则返回0;若k为1,则返回1,此时只有根节点符合要求。

接下来,在左右子树中递归查找第k-1层的节点,而后将左右子树第k-1层的节点个数加起来,最终得到母树第k层的节点个数。

最后,返回size变量即可。


 // 获取第K层节点的个数
    int getKLevelNodeCount(BTNode root, int k) {
        int size = 0;
        if (root == null)
            return 0;
        if (k == 1)
            return 1;
        size = size + getKLevelNodeCount(root.left, k - 1);
        size = size + getKLevelNodeCount(root.right, k - 1);
        return size;
    }

2.4获取二叉树的高度  

我们实现一个函数名为 getHeight,接受一个 BTNode 类型的参数 root,返回一个整型值表示二叉树的高度。其实现过程是通过递归方式计算根节点的左右子树高度的最大值,然后加上 1,即为整棵二叉树的高度。其中,当传入的二叉树为空时,直接返回 0。

值得注意的是,该代码使用了 Math.max 函数来比较左右子树高度的大小。这是 Java 内置的一个函数,可以用来获取两个数中的最大值。


  int getHeight(BTNode root) {
        int height = 0;
        if (root == null)
            return 0;
        return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
    }

2.5 检测值为value的元素是否存在

定义一个函数名为find,函数输入参数是一个二叉树的根节点 root 和要查找的值 val,返回值是该值所在的二叉树节点。

具体实现方式是,先判断当前根节点是否为 null,若是则返回 null;若当前节点的值与目标值相等,则返回该节点;否则分别在左子树和右子树中递归查找目标值。如果左右子树都没有找到目标值,则返回 null,如果找到目标值则返回目标值所在的节点

// 检测值为value的元素是否存在
    BTNode find(BTNode root, int val) {
        if (root == null)
            return null;
        if (root.value == val)
            return root;
        BTNode btNode1 = find(root.left, val);
        if (btNode1 != null)
            return btNode1;
        BTNode btNode2 = find(root.right, val);
        if (btNode2 != null)
            return btNode2;

        return null;
    }

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

其主要思路是通过 BFS(广度优先搜索)算法逐层遍历树,并在遇到第一个空节点时退出循环。然后再检查队列中是否还存在非空节点,若存在,则不是完全二叉树;若不存在,则是完全二叉树。具体解释可见下面分析:

  1. 函数名:isCompleteTree 返回值:boolean类型,表示是否为完全二叉树 参数:BTNode类型,表示二叉树的根节点

  2. 判断根节点是否为空,若为空,则直接返回 true,因为空树也可以看作是完全二叉树。

  3. 创建一个队列 queue,将根节点加入队列。

  4. 开始循环,当队列不为空时,循环体内部分以下操作: a. 取出队首元素 btNode1。 b. 若 btNode1 不为空,则将其左右儿子加入队列。 c. 若 btNode1 为空,则退出循环。

  5. 循环结束后,检查队列中是否还有非空节点。若有,则不是完全二叉树;若没有,则是完全二叉树。(我们能将null输入到队列里,同理队列也能输出null)

  6. 返回判断结果。

注意一个重要的点,之前栈和队列中讲过该知识点:栈和队列都允许存储null值。在栈和队列中,null值被视为一种有效的元素,因此可以被添加到栈和队列中,作为一个元素去存放。

我们如果不清楚该知识点的话这题是绝对想不到怎么解决的,毕竟该题是把null存储在队列中去解决问题的,如果你连null是否能存储在队列中都不清楚的话,又谈何去做该题。

 //判断一棵树是不是完全二叉树
  public  boolean isCompleteTree(BTNode root) {
      if (root == null)
          return true;
      Queue<BTNode> queue = new LinkedList<>();
      queue.offer(root);
      while (!queue.isEmpty()) {
          BTNode btNode1 = queue.poll();
          if (btNode1 != null) {
              queue.offer(btNode1.left);
              queue.offer(btNode1.right);
          } else {
                   break;
          }}
          while(!queue.isEmpty()){
              if(queue.peek()!=null)
                  return false;
              else
                  queue.poll();
          }
                return  true;
  }

2.7遍历 


2.7.1先序遍历

二叉树的先序遍历 遍历顺序为:根节点 -> 左子树 -> 右子树。具体实现步骤如下:

  1. 判断二叉树节点是否为空,如果为空则直接返回。
  2. 输出当前节点的值。
  3. 递归调用前序遍历函数,遍历当前节点的左子树。
  4. 递归调用前序遍历函数,遍历当前节点的右子树。
 //先序遍历
    public void preorder(BTNode btNode) {
        if (btNode == null)
            return;
        System.out.print(btNode.value + " ");
        preorder(btNode.left);
        preorder(btNode.right);
    }

2.7.2中序遍历 

中序遍历是二叉树遍历中的一种,它的遍历顺序是从左子树开始,到根节点,再到右子树。具体实现如下:

  1. 首先判断当前节点是否为 null,如果是则返回。
  2. 对当前节点的左子树进行递归 中序遍历。
  3. 遍历左子树完成后,输出当前节点的值。
  4. 对当前节点的右子树进行递归中序遍历。
  //中序遍历
    public void inorder(BTNode btNode) {
        if (btNode == null)
            return;
        inorder(btNode.left);
        System.out.print(btNode.value + " ");
        inorder(btNode.right);
    }

2.7.3后序遍历

后序遍历是指先访问左子树,再访问右子树,最后访问根节点的遍历方式。具体分析如下:

  1. 首先判断当前节点是否为空,如果为空则直接返回。
  2. 递归后序遍历 遍历当前节点的左子树。
  3. 递归后序遍历 遍历当前节点的右子树。
  4. 输出当前节点的值。
//后序遍历
public void postorder(BTNode btNode) {
if (btNode == null)
return;
postorder(btNode.left);
postorder(btNode.right);
System.out.print(btNode.value + " ");
}

2.7.4层序遍历 

层序遍历是指从根节点开始,按照从上到下、从左到右的顺序依次访问二叉树中的每一个节点。具体分析如下:

  1. 首先判断二叉树的根节点是否为空,如果为空则直接返回。

  2. 创建一个队列(这里使用 Java 中的 LinkedList 实现),将根节点加入队列中。

  3. 当队列不为空时,重复以下操作:

    a. 取出队头元素。

    b. 输出队头元素的值。

    c. 如果队头元素有左子节点,则将左子节点加入队列。

    d. 如果队头元素有右子节点,则将右子节点加入队列。

  4. 当队列为空时,说明遍历完成,退出循环。

  //层序遍历
   public  void levelOrder(BTNode btNode) {
       if (btNode == null)
           return;
       Queue<BTNode> queue = new LinkedList<>();
       queue.offer(btNode);
       while (!queue.isEmpty()){
             BTNode btNode1=queue.poll();
           System.out.print(btNode1.value+"  ");
           if(btNode1.left!=null)
              queue.offer(btNode1.left);
           if(btNode1.right!=null)
              queue.offer(btNode1.right);
       }
   }

 3.二叉树的模拟——使用

  以下是模拟的二叉树的全部代码

public class BinaryTree {
    static class BTNode {
        int value;
        BTNode left;
        BTNode right;

        public BTNode(int value){
        this.value = value;
        }
    }

    public BTNode creatBinaryTree() {
        BTNode btNode1 = new BTNode(1);
        BTNode btNode2 = new BTNode(2);
        BTNode btNode3 = new BTNode(3);
        BTNode btNode4 = new BTNode(4);
        BTNode btNode5 = new BTNode(5);
        BTNode btNode6 = new BTNode(6);
        BTNode btNode7 = new BTNode(7);
        btNode1.left = btNode2;
        btNode1.right = btNode3;
        btNode2.left = btNode4;
        btNode2.right = btNode5;
        btNode3.right = btNode6;
        btNode5.left = btNode7;
        return btNode1;
    }


    //先序遍历
    public void preorder(BTNode btNode) {
        if (btNode == null)
            return;
        System.out.print(btNode.value + " ");
        preorder(btNode.left);
        preorder(btNode.right);
    }

    //中序遍历
    public void inorder(BTNode btNode) {
        if (btNode == null)
            return;
        inorder(btNode.left);
        System.out.print(btNode.value + " ");
        inorder(btNode.right);
    }

    //后序遍历
    public void postorder(BTNode btNode) {
        if (btNode == null)
            return;
        postorder(btNode.left);
        postorder(btNode.right);
        System.out.print(btNode.value + " ");
    }
    //层序遍历
   public  void levelOrder(BTNode btNode) {
       if (btNode == null)
           return;
       Queue<BTNode> queue = new LinkedList<>();
       queue.offer(btNode);
       while (!queue.isEmpty()){
             BTNode btNode1=queue.poll();
           System.out.print(btNode1.value+"  ");
           if(btNode1.left!=null)
              queue.offer(btNode1.left);
           if(btNode1.right!=null)
              queue.offer(btNode1.right);
       }
   }

    //得出树的节点数量
    int size(BTNode root) {
        int size = 0;
        if (root == null)
            return 0;
        size++;
        size = size + size(root.left);
        size = size + size(root.right);
        return size;
    }

    // 获取叶子节点的个数
    int getLeafNodeCount(BTNode root) {
        int size = 0;
        if (root == null)
            return 0;
        if ((root.left == null) && (root.right == null))
            size++;
        size = size + getLeafNodeCount(root.left);
        size = size + getLeafNodeCount(root.right);
        return size;
    }

    // 获取第K层节点的个数
    int getKLevelNodeCount(BTNode root, int k) {
        int size = 0;
        if (root == null)
            return 0;
        if (k == 1)
            return 1;
        size = size + getKLevelNodeCount(root.left, k - 1);
        size = size + getKLevelNodeCount(root.right, k - 1);
        return size;
    }


    // 获取二叉树的高度
    int getHeight(BTNode root) {
        int height = 0;
        if (root == null)
            return 0;
        return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
    }

    // 检测值为value的元素是否存在
    BTNode find(BTNode root, int val) {
        if (root == null)
            return null;
        if (root.value == val)
            return root;
        BTNode btNode1 = find(root.left, val);
        if (btNode1 != null)
            return btNode1;
        BTNode btNode2 = find(root.right, val);
        if (btNode2 != null)
            return btNode2;

        return null;
    }

//判断一棵树是不是完全二叉树
  public  boolean isCompleteTree(BTNode root) {
      if (root == null)
          return true;
      Queue<BTNode> queue = new LinkedList<>();
      queue.offer(root);
      while (!queue.isEmpty()) {
          BTNode btNode1 = queue.poll();
          if (btNode1 != null) {
              queue.offer(btNode1.left);
              queue.offer(btNode1.right);
          } else {
                   break;
          }}
          while(!queue.isEmpty()){
              if(queue.peek()!=null)
                  return false;
              else
                  queue.poll();
          }
                return  true;
  }
}

我们将对上述模拟的二叉树进行使用,代码如下:

 
public class Test1 {
    public static void main(String[] args) {
        BinaryTree binaryTree=new BinaryTree();
        BinaryTree.BTNode btNode=binaryTree.creatBinaryTree();
        binaryTree.preorder(btNode);
        System.out.println();
        binaryTree.inorder(btNode);
        System.out.println();
        binaryTree.postorder(btNode);
        System.out.println();
        binaryTree.levelOrder(btNode);
        System.out.println();
        System.out.println(binaryTree.size(btNode));//节点个数
        System.out.println(binaryTree.getLeafNodeCount(btNode));//叶子节点个数
        System.out.println(binaryTree.getKLevelNodeCount(btNode, 3));//树的第三层的节点数
        System.out.println(binaryTree.getHeight(btNode));//树的高度
        System.out.println(binaryTree.size(binaryTree.find(btNode, 2)));
        //检测树中值为2的节点是否存在,如果存在,打印出该节点作为根节点时所代表的子树的节点数
        System.out.println(binaryTree.isCompleteTree(btNode));//检测是否为完全二叉树
    }


}

 创建的树如下:


执行之后的结果如下:


我们发现其执行结果是如我们预料的一样,完全正确,所以二叉树的模拟就成功了,之后可以安心使用它了。

4.特别说明 

对于我们上述模拟出来的二叉树,其在集合框架中并没有对应的类去实现。

那没有对应的类去实现它?我们为什么还要模拟呢?不白白浪费精力?

其实,我们之所以模拟出来这个二叉树,是为了打好基础。虽然我们模拟出来的这个二叉树并没有对应的类去实现,但在之后的学习中我们会学到堆,红黑树等,这些也都是二叉树,并且这些二叉树在集合框架中会有对应类去实现它们,所以我们现在模拟一个二叉树只是为了对二叉树有个更清晰的认知,为后序的堆,红黑树等其他一些二叉树的学习打好基础。

5.总结

所以这篇文章结束后,我们的二叉树的知识点就全讲解完了,下篇文章将会给大家带来二叉树的习题讲解。在此,我们诚挚地邀请各位大佬们为我们点赞、关注,并在评论区留下您宝贵的意见与建议。让我们共同学习,共同进步,为知识的海洋增添更多宝贵的财富!🎉🎉🎉❤️❤️💕💕🥳👏👏👏 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WPF Treeview控件开虚拟化后定位节点

不开虚拟化&#xff0c;可以用下面的方法直接定位 <Window x:Class"WpfApplication2.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"Title"Main…

Qt OPC UA通信

介绍 OPC UA全称Open Platform Unified Architecture&#xff0c;开放平台统一架构&#xff0c;是工业自动化领域通用的数据交换协议&#xff0c;它有两套主要的通信机制&#xff1a;1.客户端-服务器通信&#xff1b;2.发布订阅。Qt对OPC UA通信标准也提供了支持&#xff0c;目…

JDBC学习笔记(三)高级篇

一、JDBC 优化及工具类封装 1.1 现有问题 1.2 JDBC 工具类封装 V1.0 resources/db.properties配置文件&#xff1a; driverClassNamecom.mysql.cj.jdbc.Driver urljdbc:mysql:///atguigu usernameroot password123456 initialSize10 maxActive20 工具类代码&#xff1a; p…

代码随想录算法训练营第二十八天|93.复原IP地址 ,78.子集 ,90.子集II

93. 复原 IP 地址 - 力扣&#xff08;LeetCode&#xff09; class Solution {ArrayList<String> results new ArrayList<>();public List<String> restoreIpAddresses(String s) {if(s.length() > 12){return new ArrayList<>();}char[] ipChars …

f4pga环境搭建教程

f4pga环境搭建教程 背景介绍 FOSS Flows For FPGA (F4PGA) project&#xff0c;是一套开源的FPGA工具链&#xff0c;号称the GCC of FPGAs&#xff0c;作用是将写的硬件描述语言&#xff08;verilog或VHDL&#xff09;转化为可以在FPGA上运行的可执行文件&#xff08;bit文件…

Python实现PPT表格的编写包含新建修改插图(收藏备用)

自动创建一个ppt文件并创建好表格 代码要用到pptx库 pip install python-pptx 创建含有表格的ppt文件代码&#xff1a; from pptx import Presentation from pptx.util import Inches# 创建一个PPT对象 ppt Presentation()# 添加一个幻灯片 slide ppt.slides.add_slide(p…

原美团项目管理专业通道执行主席边国华受邀为第十三届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会 峰项标&#xff08;北京&#xff09;管理咨询有限公司常务副总裁、原美团项目管理专业通道执行主席边国华先生受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾&#xff0c;演讲议题为“从组织级项目管理能力的评价角度看企业实践”。大会将于6月2…

Python读取字节数组

读取和处理bytearray中的值 # 输出&#xff1a;Combined 16-bit value: 1234 python-can发送和接收CAN报文 import can # 创建一个CAN总线对象&#xff08;这取决于你的硬件和驱动程序&#xff09; bus can.interface.Bus(channelcan0, bustypesocketcan) # 定义一个CAN…

django 内置 JSON 字段 使用场景

Django 内置的 JSON 字段&#xff08;JSONField&#xff09;是在 Django 3.1 版本中引入的&#xff0c;用于处理 JSON 格式的数据。JSONField 允许在数据库表中存储和查询 JSON 数据&#xff0c;并且在与 Python 代码交互时自动转换为合适的 Python 数据类型。以下是一些常见的…

成都欣丰洪泰文化传媒有限公司好不好?

在数字经济的浪潮中&#xff0c;电商行业以其独特的魅力和无限的发展潜力&#xff0c;吸引了越来越多的企业和个人投身其中。作为电商服务领域的佼佼者&#xff0c;成都欣丰洪泰文化传媒有限公司凭借专业的团队、优质的服务和创新的理念&#xff0c;不断引领电商新风尚&#xf…

INT202 例题

算法复杂度 O(n)&#xff1a;表示算法的渐进上界。如果一个算法的运行时间是O(n)&#xff0c;那么它的运行时间最多与输入规模n成正比。换句话说&#xff0c;当输入规模n增加时&#xff0c;算法的运行时间不会超过某个常数倍的n。比如&#xff0c;如果一个算法的时间复杂度是O(…

AndroidStudio使用高德地图API获取手机定位

一、高德地图API申请 首先去高德注册开发者账号 下面这两个选项&#xff0c;也是我们项目成功的关键 1.1怎么获取SHA1指纹密码 ①使用AS自带的签名文件 你的用户文件下面会有一个.android文件夹,进入文件夹,在这个路径下打开cmd 如果.android下面没有签名文件参考创建文章 …

【管理咨询宝藏124】通过BLM打通前端业务与财务的双轨制设计方案

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏124】通过BLM打通前端业务与财务的双轨制设计方案 【格式】PDF版本 【关键词】BLM、组织架构设计、流程优化 【核心观点】 - 运用“拉通业务财务…

【原创】springboot+mysql大学生综合素质测评管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

【python】成功解决“ValueError: Expected 2D array, got 1D array instead”错误的全面指南

成功解决“ValueError: Expected 2D array, got 1D array instead”错误的全面指南 一、引言 在Python的数据分析和机器学习领域&#xff0c;尤其是使用NumPy、Pandas、scikit-learn等库时&#xff0c;经常会遇到各种类型错误。其中&#xff0c;“ValueError: Expected 2D arr…

MP-SPDZ的学习与运用

目录 MP-SPDZ 的介绍主要功能典型应用场景 MP-SPDZ 的安装实验环境准备环境安装MP-SPDZ 下载和编译 MP-SPDZ 的使用测试程序第三方求和三方计算测试冒泡排序比较运算函数语法详解——Sint语法详解——Array基于AES电路实现OPRFORAM隐私集合求交实现两台虚拟机之间进行MPC简单实…

视觉SLAM十四讲:从理论到实践(Chapter8:视觉里程计2)

前言 学习笔记&#xff0c;仅供学习&#xff0c;不做商用&#xff0c;如有侵权&#xff0c;联系我删除即可 一、目标 1.理解光流法跟踪特征点的原理。 2.理解直接法是如何估计相机位姿的。 3.实现多层直接法的计算。 特征点法存在缺陷&#xff1a; 二、光流(Optical Flow) …

SEO之关键词扩展(二)

初创企业搭建网站的朋友看1号文章&#xff1b;想学习云计算&#xff0c;怎么入门看2号文章谢谢支持&#xff1a; 1、我给不会敲代码又想搭建网站的人建议 2、新手上云 &#xff08;接上一篇。。。&#xff09; 5、各种形式的变体 1.同义词 假设核心关键词是酒店&#xff0c;…

Python版《消消乐》,附源码

曾经风靡一时的消消乐&#xff0c;至今坐在地铁上都可以看到很多人依然在玩&#xff0c;想当年我也是大军中的一员&#xff0c;那家伙&#xff0c;吃饭都在玩&#xff0c;进入到高级的那种胜利感还是很爽的&#xff0c;连续消&#xff0c;无限消&#xff0c;哈哈&#xff0c;现…

Kotlin中的StateFlow和SharedFlow有什么区别?

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 在Kotlin的协程库kotlinx.coroutines中&#xff0c;StateFlow和SharedFlow是两种用于处理事件流的API&#xff0c;它们有相似之处&#xff0c;但…