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

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪)
原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)
上一篇:《数据结构第4章 数组和广义表》

目录

    • zero:思维导图
    • 一、树的基本概念
      • 1. 什么是树?
      • 2. 树的基本术语
      • 3. 树的存储结构
        • 顺序存储 - 双亲表示法
        • 链式存储 - 孩子兄弟表示法
    • 二、二叉树详解
      • 1. 二叉树的定义与特点
      • 2. 特殊的二叉树类型
        • 满二叉树
        • 完全二叉树
        • 二叉排序树(BST)
        • 平衡二叉树(AVL树)
      • 3. 二叉树的重要性质
      • 4. 二叉树的存储结构
        • 顺序存储
        • 链式存储(最常用)
      • 5. 二叉树的遍历
        • 先序遍历(根-左-右)
        • 中序遍历(左-根-右)
        • 后序遍历(左-右-根)
        • 层序遍历(使用队列)
      • 6. 线索二叉树
    • 三、树、森林与二叉树的转换
      • 1. 树转二叉树
      • 2. 森林转二叉树
      • 3. 遍历关系
    • 四、树和二叉树的应用
      • 1. 哈夫曼树与哈夫曼编码
        • 什么是哈夫曼树?
        • 哈夫曼算法构造步骤
        • 哈夫曼编码
      • 2. 并查集
    • 五、实战编程与常见问题
      • 1. 经典算法实现
        • 求二叉树的高度
        • 统计二叉树结点个数
        • 判断是否为完全二叉树
      • 2. 面试高频题目
        • 题目1:二叉树的镜像
        • 题目2:二叉树的最大路径和
        • 题目3:验证二叉搜索树
      • 3. 性能优化技巧
        • 非递归遍历(避免栈溢出)
        • 层序遍历的变种(按层输出)
      • 4. 实际应用案例
        • 文件系统目录树
    • 总结

zero:思维导图

在这里插入图片描述

一、树的基本概念

1. 什么是树?

想象一下家族族谱或者公司的组织架构图,它们都是典型的树结构。在计算机中,(Tree)是由结点(Node)和(Edge)组成的层次型数据结构。

2. 树的基本术语

让我们通过一个直观的例子来理解这些术语:

在这里插入图片描述

  • 根结点:树的顶端,没有父结点的结点(就像族谱中的祖先)
  • 父结点(双亲结点):上一层的结点
  • 子结点(孩子结点):下一层的结点
  • 兄弟结点:同一个父结点的子结点
  • 叶子结点:没有子结点的结点(度为0)
  • 分支结点:有子结点的结点(度大于0)
  • 树的高度/深度:从根到叶子的最长路径上的结点数
  • 路径长度:路径上边的个数

3. 树的存储结构

顺序存储 - 双亲表示法

在这里插入图片描述

这种方法用数组存储,每个结点保存数据父结点的下标

typedef struct {char data;      // 结点数据int parent;     // 父结点下标,根结点为-1
} PTNode;typedef struct {PTNode nodes[MAXSIZE];int nodeCount;  // 结点数量
} PTree;
链式存储 - 孩子兄弟表示法

在这里插入图片描述

采用"左孩子右兄弟"的策略,每个结点包含:

  • 数据域
  • 指向第一个孩子的指针
  • 指向右兄弟的指针
typedef struct TreeNode {char data;struct TreeNode* firstChild;  // 第一个孩子struct TreeNode* nextSibling; // 右兄弟
} TreeNode;

二、二叉树详解

1. 二叉树的定义与特点

二叉树(Binary Tree)是每个结点最多有两个子结点的树结构,具有以下特点:

  • 每个结点的度不超过2(最多2个孩子)

  • 子树有左右之分,顺序不能颠倒

  • 即使只有一个子结点,也要明确是左孩子还是右孩子

    A.b为a的左子树

    在这里插入图片描述
    B.c为a的右子树
    在这里插入图片描述

2. 特殊的二叉树类型

在这里插入图片描述

满二叉树

高度为h,含有 2^h - 1 个结点的二叉树。特点是每一层都"满员"。

在这里插入图片描述

完全二叉树

除了最后一层,其他层都是满的,且最后一层的结点都靠左排列

在这里插入图片描述

反例:

在这里插入图片描述

二叉排序树(BST)

满足"左 < 根 < 右"性质的二叉树,支持高效的查找操作。

在这里插入图片描述
在这里插入图片描述

平衡二叉树(AVL树)

任意结点的左右子树高度差不超过1的二叉排序树。

在这里插入图片描述

3. 二叉树的重要性质

  • 性质1:叶结点数 = 度为2的结点数 + 1 即: n 0 = n 2 + 1 n_0 = n_2 +1 n0=n2+1
  • 性质2:第k层最多有 2^(k-1) 个结点
  • 性质3:高度为h的二叉树最多有 2^h - 1 个结点
  • 性质4:n个结点的完全二叉树高度为 ⌊log₂n⌋ + 1

4. 二叉树的存储结构

顺序存储

使用数组,下标之间有规律:

  • 结点i的左孩子:2i
  • 结点i的右孩子:2i + 1
  • 结点i的父结点:⌊i/2⌋

a.完全二叉树的顺序存储

在这里插入图片描述

b.非完全二叉树(一般二叉树)的顺序存储

在这里插入图片描述
可以看出非完全二叉树会浪费很多存储单元,不适合进行顺序存储

链式存储(最常用)
typedef struct BiTNode {char data;                  // 数据域struct BiTNode* lchild;     // 左孩子指针struct BiTNode* rchild;     // 右孩子指针
} BiTNode, *BiTree;

在这里插入图片描述

5. 二叉树的遍历

二叉树遍历是指按照某种规则访问每个结点有且仅有一次

在这里插入图片描述

先序遍历(根-左-右)
void PreOrder(BiTree T) {if (T) {visit(T);           // 访问根结点PreOrder(T->lchild); // 遍历左子树PreOrder(T->rchild); // 遍历右子树}
}
中序遍历(左-根-右)
void InOrder(BiTree T) {if (T) {InOrder(T->lchild);  // 遍历左子树visit(T);            // 访问根结点InOrder(T->rchild);  // 遍历右子树}
}
后序遍历(左-右-根)
void PostOrder(BiTree T) {if (T) {PostOrder(T->lchild); // 遍历左子树PostOrder(T->rchild); // 遍历右子树visit(T);             // 访问根结点}
}
层序遍历(使用队列)
void LevelOrder(BiTree T) {Queue Q;InitQueue(&Q);if (T) EnQueue(&Q, T);while (!IsEmpty(Q)) {DeQueue(&Q, &T);visit(T);if (T->lchild) EnQueue(&Q, T->lchild);if (T->rchild) EnQueue(&Q, T->rchild);}
}

6. 线索二叉树

线索二叉树是利用空闲指针域存储前驱和后继信息的特殊二叉树。

typedef struct ThreadNode {char data;struct ThreadNode* lchild, *rchild;int ltag, rtag;  // 0表示指向孩子,1表示指向线索
} ThreadNode, *ThreadTree;

优点:可以快速找到前驱和后继结点,提高遍历效率
缺点:插入删除操作变复杂

三、树、森林与二叉树的转换

1. 树转二叉树

口诀:“加线、抹线、旋转”

  1. 加线:兄弟结点间连虚线
  2. 抹线:只保留每个结点与最左孩子的连线
  3. 旋转:虚线向右下方旋转45°

在这里插入图片描述

2. 森林转二叉树

  1. 先将森林中每棵树转换为二叉树
  2. 将后面的二叉树作为前面二叉树根结点的右子树

在这里插入图片描述

3. 遍历关系

  • 树的先根遍历二叉树的先序遍历
  • 树的后根遍历二叉树的中序遍历
  • 森林的先序遍历二叉树的先序遍历

在这里插入图片描述

四、树和二叉树的应用

1. 哈夫曼树与哈夫曼编码

什么是哈夫曼树?

哈夫曼树带权路径长度最短的二叉树,广泛应用于数据压缩。

在这里插入图片描述

关键概念

  • 带权路径长度 = 路径长度 × 结点权值
  • 树的带权路径长度 = 所有叶结点的带权路径长度之和
哈夫曼算法构造步骤
  1. 将所有结点放入优先队列(按权值排序)
  2. 每次取出两个权值最小的结点
  3. 创建新结点作为它们的父结点,权值为两者之和
  4. 将新结点放回队列
  5. 重复直到只剩一个结点(根结点)
哈夫曼编码
  • 左分支标0,右分支标1(或相反)
  • 从根到叶结点的路径就是该字符的编码
  • 保证前缀编码性质:任何编码都不是其他编码的前缀

在这里插入图片描述

特点

  • 频率高的字符编码短
  • 频率低的字符编码长
  • 平均编码长度最短

2. 并查集

并查集是处理不相交集合的树型数据结构。

核心操作

  • Find(x):查找x属于哪个集合
  • Union(x, y):合并x和y所在的集合
// 查找操作(带路径压缩)
int Find(int x) {if (parent[x] != x) {parent[x] = Find(parent[x]);  // 路径压缩}return parent[x];
}// 合并操作
void Union(int x, int y) {int rootX = Find(x);int rootY = Find(y);if (rootX != rootY) {parent[rootX] = rootY;}
}

五、实战编程与常见问题

1. 经典算法实现

求二叉树的高度
// 递归求二叉树高度
int TreeHeight(BiTree T) {if (T == NULL) return 0;int leftHeight = TreeHeight(T->lchild);int rightHeight = TreeHeight(T->rchild);return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}
统计二叉树结点个数
// 递归统计结点数
int CountNodes(BiTree T) {if (T == NULL) return 0;return CountNodes(T->lchild) + CountNodes(T->rchild) + 1;
}
判断是否为完全二叉树
bool IsComplete(BiTree T) {if (T == NULL) return true;Queue Q;InitQueue(&Q);EnQueue(&Q, T);bool flag = false;  // 标记是否遇到空结点while (!IsEmpty(Q)) {BiTree current;DeQueue(&Q, &current);if (current == NULL) {flag = true;} else {if (flag) return false;  // 遇到空结点后又遇到非空结点EnQueue(&Q, current->lchild);EnQueue(&Q, current->rchild);}}return true;
}

2. 面试高频题目

题目1:二叉树的镜像

问题:翻转一棵二叉树(每个结点的左右子树交换)

BiTree MirrorTree(BiTree T) {if (T == NULL) return NULL;// 交换左右子树BiTree temp = T->lchild;T->lchild = T->rchild;T->rchild = temp;// 递归处理子树MirrorTree(T->lchild);MirrorTree(T->rchild);return T;
}
题目2:二叉树的最大路径和

问题:给定一个二叉树,找到任意一条路径的最大数字和

int maxSum = INT_MIN;int MaxPathSumHelper(BiTree T) {if (T == NULL) return 0;// 递归计算左右子树的最大贡献值int left = max(0, MaxPathSumHelper(T->lchild));int right = max(0, MaxPathSumHelper(T->rchild));// 当前路径的最大值int currentMax = T->data + left + right;maxSum = max(maxSum, currentMax);// 返回以当前结点为根的最大路径和return T->data + max(left, right);
}
题目3:验证二叉搜索树
bool IsValidBST(BiTree T, int minVal, int maxVal) {if (T == NULL) return true;if (T->data <= minVal || T->data >= maxVal) {return false;}return IsValidBST(T->lchild, minVal, T->data) && IsValidBST(T->rchild, T->data, maxVal);
}// 调用入口
bool ValidateBST(BiTree T) {return IsValidBST(T, INT_MIN, INT_MAX);
}

3. 性能优化技巧

非递归遍历(避免栈溢出)
// 非递归中序遍历
void InOrderNonRecursive(BiTree T) {Stack S;InitStack(&S);BiTree current = T;while (current != NULL || !IsEmpty(S)) {// 一直向左走到底while (current != NULL) {Push(&S, current);current = current->lchild;}// 弹出并访问结点Pop(&S, &current);visit(current);// 转向右子树current = current->rchild;}
}
层序遍历的变种(按层输出)
void PrintByLevel(BiTree T) {if (T == NULL) return;Queue Q;InitQueue(&Q);EnQueue(&Q, T);while (!IsEmpty(Q)) {int levelSize = QueueSize(&Q);// 处理当前层的所有结点for (int i = 0; i < levelSize; i++) {BiTree current;DeQueue(&Q, &current);printf("%d ", current->data);if (current->lchild) EnQueue(&Q, current->lchild);if (current->rchild) EnQueue(&Q, current->rchild);}printf("\n");  // 换行表示层结束}
}

4. 实际应用案例

文件系统目录树
typedef struct FileNode {char name[256];bool isDirectory;struct FileNode* firstChild;struct FileNode* nextSibling;struct FileNode* parent;
} FileNode;// 添加子文件/目录
void AddChild(FileNode* parent, FileNode* child) {child->parent = parent;child->nextSibling = parent->firstChild;parent->firstChild = child;
}// 遍历目录(类似树的先根遍历)
void ListDirectory(FileNode* root, int depth) {if (root == NULL) return;// 打印缩进for (int i = 0; i < depth; i++) printf("  ");printf("%s%s\n", root->name, root->isDirectory ? "/" : "");// 递归遍历子目录FileNode* child = root->firstChild;while (child != NULL) {ListDirectory(child, depth + 1);child = child->nextSibling;}
}

总结

树和二叉树是数据结构中的重要概念,它们以层次化的方式组织数据,具有以下特点:

  1. 树结构模拟了现实世界的层次关系,直观易懂
  2. 二叉树是最重要的树类型,支持多种高效的操作
  3. 遍历算法是操作树的基础,四种遍历方式各有用途
  4. 转换技巧:"左孩子右兄弟"是树与二叉树转换的核心
  5. 实际应用广泛:文件系统、表达式求值、数据压缩、数据库索引等

通过本章的学习,我们不仅掌握了树的理论知识,还学会了实际编程技巧。树结构的思想将伴随我们整个编程生涯,从简单的文件管理到复杂的算法设计,都离不开树的概念。

在后续的学习中,我们还会遇到更多基于树的高级数据结构,如堆、B树、红黑树等。掌握好基础的树和二叉树知识,将为学习这些高级结构打下坚实的基础。

📝 学习小贴士树结构无处不在!下次看到文件夹、组织架构图、族谱时,不妨想想它们的树结构特点,这样能帮助你更好地理解和应用树的概念。

Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder)
点赞加关注,收藏不迷路!本篇文章对你有帮助的话,还请多多点赞支持!

相关文章:

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 原创笔记&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;《数据结构第4章 数组和广义表》…...

Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程

鸿蒙电脑版操作系统来了&#xff0c;很多小伙伴想体验鸿蒙电脑版操作系统&#xff0c;可惜&#xff0c;鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机&#xff0c;来体验大家心心念念的鸿蒙系统啦&#xff01;注意&#xff1a;虚拟…...

CppCon 2015 学习:Time Programming Fundamentals

Civil Time 公历时间 特点&#xff1a; 共 6 个字段&#xff1a; Year&#xff08;年&#xff09;Month&#xff08;月&#xff09;Day&#xff08;日&#xff09;Hour&#xff08;小时&#xff09;Minute&#xff08;分钟&#xff09;Second&#xff08;秒&#xff09; 表示…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)

引言 在嵌入式系统中&#xff0c;用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例&#xff0c;介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单&#xff0c;执行相应操作&#xff0c;并提供平滑的滚动动画效果。 本文设计了一个…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…...

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”

案例&#xff1a; 某医药分销企业&#xff0c;主要经营各类药品的批发与零售。由于药品的特殊性&#xff0c;效期管理至关重要&#xff0c;但该企业一直面临效期问题的困扰。在未使用WMS系统之前&#xff0c;其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

从零开始了解数据采集(二十八)——制造业数字孪生

近年来&#xff0c;我国的工业领域正经历一场前所未有的数字化变革&#xff0c;从“双碳目标”到工业互联网平台的推广&#xff0c;国家政策和市场需求共同推动了制造业的升级。在这场变革中&#xff0c;数字孪生技术成为备受关注的关键工具&#xff0c;它不仅让企业“看见”设…...

AD学习(3)

1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分&#xff1a; &#xff08;1&#xff09;PCB焊盘&#xff1a;表层的铜 &#xff0c;top层的铜 &#xff08;2&#xff09;管脚序号&#xff1a;用来关联原理图中的管脚的序号&#xff0c;原理图的序号需要和PCB封装一一…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

Vue 3 + WebSocket 实战:公司通知实时推送功能详解

&#x1f4e2; Vue 3 WebSocket 实战&#xff1a;公司通知实时推送功能详解 &#x1f4cc; 收藏 点赞 关注&#xff0c;项目中要用到推送功能时就不怕找不到了&#xff01; 实时通知是企业系统中常见的功能&#xff0c;比如&#xff1a;管理员发布通知后&#xff0c;所有用户…...

倒装芯片凸点成型工艺

UBM&#xff08;Under Bump Metallization&#xff09;与Bump&#xff08;焊球&#xff09;形成工艺流程。我们可以将整张流程图分为三大阶段来理解&#xff1a; &#x1f527; 一、UBM&#xff08;Under Bump Metallization&#xff09;工艺流程&#xff08;黄色区域&#xff…...

2.3 物理层设备

在这个视频中&#xff0c;我们要学习工作在物理层的两种网络设备&#xff0c;分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间&#xff0c;需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质&#xff0c;假设A节点要给…...

Qt的学习(一)

1.什么是Qt Qt特指用来进行桌面应用开发&#xff08;电脑上写的程序&#xff09;涉及到的一套技术Qt无法开发网页前端&#xff0c;也不能开发移动应用。 客户端开发的重要任务&#xff1a;编写和用户交互的界面。一般来说和用户交互的界面&#xff0c;有两种典型风格&…...

鸿蒙HarmonyOS 5军旗小游戏实现指南

1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;采用DevEco Studio实现&#xff0c;包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

Spring AOP代理对象生成原理

代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】&#xff0c;这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...

在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南

在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...

密码学基础——SM4算法

博客主页&#xff1a;christine-rr-CSDN博客 ​​​​专栏主页&#xff1a;密码学 &#x1f4cc; 【今日更新】&#x1f4cc; 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 ​编辑…...

aardio 自动识别验证码输入

技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”&#xff0c;于是尝试整合图像识别与网页自动化技术&#xff0c;完成了这套模拟登录流程。核心思路是&#xff1a;截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...

机器学习的数学基础:线性模型

线性模型 线性模型的基本形式为&#xff1a; f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法&#xff0c;得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...

多元隐函数 偏导公式

我们来推导隐函数 z z ( x , y ) z z(x, y) zz(x,y) 的偏导公式&#xff0c;给定一个隐函数关系&#xff1a; F ( x , y , z ( x , y ) ) 0 F(x, y, z(x, y)) 0 F(x,y,z(x,y))0 &#x1f9e0; 目标&#xff1a; 求 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z​、 …...

基于单片机的宠物屋智能系统设计与实现(论文+源码)

本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢&#xff0c;连接红外测温传感器&#xff0c;可实时精准捕捉宠物体温变化&#xff0c;以便及时发现健康异常&#xff1b;水位检测传感器时刻监测饮用水余量&#xff0c;防止宠物…...

Vue3 PC端 UI组件库我更推荐Naive UI

一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用&#xff0c;前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率&#xff0c;还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库&#xff08;Naive UI、Element …...

前端调试HTTP状态码

1xx&#xff08;信息类状态码&#xff09; 这类状态码表示临时响应&#xff0c;需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分&#xff0c;客户端应继续发送剩余部分。 2xx&#xff08;成功类状态码&#xff09; 表示请求已成功被服务器接收、理解并处…...

《Offer来了:Java面试核心知识点精讲》大纲

文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...

[特殊字符] 手撸 Redis 互斥锁那些坑

&#x1f4d6; 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作&#xff0c;想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁&#xff0c;也顺便跟 Redisson 的 RLock 机制对比了下&#xff0c;记录一波&#xff0c;别踩我踩过…...

大数据治理的常见方式

大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法&#xff0c;以下是几种常见的治理方式&#xff1a; 1. 数据质量管理 核心方法&#xff1a; 数据校验&#xff1a;建立数据校验规则&#xff08;格式、范围、一致性等&#xff09;数据清洗&…...