【高阶数据结构】揭开红黑树‘恶魔’的面具:深度解析底层逻辑

在这里插入图片描述

高阶数据结构相关知识点可以通过点击以下链接进行学习一起加油!
二叉搜索树AVL树

大家好,我是店小二,欢迎来到本篇内容!今天我们将一起探索红黑树的工作原理及部分功能实现。红黑树的概念相对抽象,但只要我们一步步深入,定能慢慢揭开它的神秘面纱

请添加图片描述
Alt
🌈个人主页:是店小二呀
🌈C语言专栏:C语言
🌈C++专栏: C++
🌈初阶数据结构专栏: 初阶数据结构
🌈高阶数据结构专栏: 高阶数据结构
🌈Linux专栏: Linux

🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅 请添加图片描述

文章目录

  • 一、红黑树概念
    • 1.1 最短和最长路径
  • 二、红黑树的节点部分
  • 三、关于红黑树的插入
    • 3.1 对某个红黑树进行分析(难点)
    • 3.2 红黑树插入逻辑(重点)
  • 四、遍历红黑树
  • 五、判断是否满足红黑树
  • 六、红黑树的删除
  • 七、红黑树与AVL树的比较
  • 八、RBTree.h

一、红黑树概念

红黑树,是一种二叉搜索树,但在每个节点上增加一个存储位表示节点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个节点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的。

在这里插入图片描述

红黑树的性质

  1. 每个节点不是红色就是黑色

  2. 根节点是黑色的

  3. 如果一个节点是红色的,则它的两个孩子节点是黑色

  4. 对于每个节点,从该节点到其后代节点的简单路径上,均包含相同数目的黑色节点

  5. 每个叶子节点都是黑色的(此处的叶子节点指的是空节点)

满足上面的性质,红黑树就能保证:其最长路径中节点个数不会超过最短路径节点个数的两倍,但是不能保证满足这样的条件就是红黑树,具体还是往下看吧,这里重点关注的是规则3、4。

1.1 最短和最长路径

  • 最短:全黑

  • 最长:一黑一红

  • 虽然有最短和最长路径,但是不一定存在最短或最长路径

在这里插入图片描述

具体说明:

  1. 对于红黑树满足最长路径中节点个数不会超过最短路径节点个数的两倍结论,是根据红黑树规则及其最短和最长路径得来的。
  2. 规则四:对于每个节点,从该节点到其后代节点的简单路径上,均包含相同数目的黑色节点。保证了每条路径黑色节点数量相同的。如果我们想要延长某一条路径,插入黑色节点不能达成目的,对此我们需要插入红色节点,碍于规则三:如果一个节点是红色的,则它的两个孩子节点是黑色的限制,对此只能在两个黑色节点之间插入一个红色节点或者在最后黑色节点插入一个红色节点。导致了最短为全黑,最长一黑一红,大致形成两倍的关系,但是不一定存在最短或最长路径(路径相同)。
  3. 红黑树的平衡维护在这微妙的关系中,如果不能保证其最长路径中节点个数不会超过最短路径节点个数的两倍就是不是红黑树,就是能保证也不一定是红黑树,不充分必要条件
  4. 使用枚举常量代替红色和黑色的含义。就是跟全部黑色节点或者全部黑色节点配合红色节点

二、红黑树的节点部分

enum Color
{RED, BLACK
};template<class K, class V> struct RBTreeNode{RBTreeNode<K, V>* _parent;RBTreeNode<K, V>* _left;RBTreeNode<K, V>* _right;pair<K, V> _kv;Color _color;RBTreeNode(const pair<K, V>& kv):_parent(nullptr),_left(nullptr),_right(nullptr),_kv(kv),_color(RED){}};

三、关于红黑树的插入

节点的插入无非两种颜色,要么红色要么黑色。如果使用严母慈父来说规则3、4的严格程度,规则3是慈父,规则4是严母。如果插入节点为黑色,必然会违法规则4,每条都会收到影响;如果插入的节点为红色,可能会违法规则3(存在连续的两个红色节点)

在这里插入图片描述

这样子不管插入啥颜色都会违法规则,如果一定要插入优选红色节点(慈父身份),接下来让我们来看,如果处理插入为红色节点,出现连续红色的问题吧。

在这里插入图片描述

3.1 对某个红黑树进行分析(难点)

前文(主要是给自己看,不懂可以评论区见)

关于这一点还是挺晕的,以下是我的看法:

  • 出现问题情况就是发生在cur和parent为红色情况下,至于为什么是在cur和parent为红色情况下。我们进行红黑树插入节点到红黑树调整结构,都是从下到上的。要么parent是黑的,cur是红的,插入没有问题;要么parent是红的,cur是黑的,插入违法规则四,不如违法规则三。所以就需要考虑cur和parent是红色的就行。
  • 既然cur和parent及其grandfather颜色是确定,问题在于uncle颜色上,所以我们分出了很多种情况,去特殊处理。
  • 规则四只是保证每条路径黑色节点数量相同,没有保证在同一层,对此在调整过程中,u就是未知的颜色,u是黑色还是不存在,我们需要根据规则去还源之前的场景,是第一种情况基础上打造了第二种情况合并为一整棵红黑树,这也是属于众多红黑树的部分。将这些特殊红黑树处理好,面对不同场景,特殊进行处理。
  • 也就是说,也是整棵红黑树的一部分

在这里插入图片描述


正文
这里我们可以确定c\p\g颜色是确定的,关键在于u颜色是不确定,从而影响整棵树的平衡

这里将情况分为两种

  1. 情况一:cur为红,p为红,g为黑,u存在且为红

  2. 情况二:cur为红,p为红,g为黑,u不存在/u存在且为黑

情况一

处理办法:将p、u改为黑,g改为红。具体流程在图中(将cur赋值给g)

在这里插入图片描述

关于红黑树分析将采取抽象图进行分析,其实这里也可以看出具体图。还是以小部分组成为大部分的思想,可以根据下图理解这个思想,就是这个结构在上面重演了。

在这里插入图片描述

在这里插入图片描述

如果在一颗高度很高红黑树中,我们可以看见红黑树在调整过程中会不断重复熟悉的场景,所以抽象图中的具体部分就被包含在其中。

第二种情况

在这里插入图片描述

对于这两种情况,就是在变色过程中,违法了规则四(严母)。如果p变色了u还是黑色或者不存在,会导致每条路径上的黑色节点个数不相等,对此跟插入黑色节点一样。

在这里插入图片描述

接下来,需要建立在这两张图进行说明,不然很容易晕的(重点)

  1. 如果u节点不存在,则cur一定是新节点。假设u节点存在,颜色为黑色,cur和p为了维护规则四,要么cur是黑色,后面跟着两个红色节点,要么p是黑色,规则四成立。然后将u节点拿出去,cur如果不是新节点,一切全部不成立,规则四直接违法。
  2. 如果u节点存在,则其一定是黑色的,那么cur节点原来的颜色一定黑色,为了遵守规则四。现在看到其是红色的原因是由于cur子树在调整的过程中将cur节点的颜色由黑色改为红色。

在这里插入图片描述

上面两种情况是根据u变量无法确认是红色还是黑色,导致影响不同。

在第二种情况的基础上,还有一个小问题就是连续红色节点不是一边独红,需要先旋转进行处理,调整到一边连续红色节点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这里将根据思路和不同功能罗列代码了,这里旋转后的节点的颜色需要自己根据图单独进行处理的。红黑树也是属于二叉搜索树,对此我们这里可以CV下代码。

右旋代码

void RotateR(Node* parent)
{Node* SubL = parent->_left;Node* SubLR = SubL->_right;parent->_left = SubLR;if (SubLR)SubLR->_parent = parent;SubL->_right = parent;Node* ppNode = parent->_parent;parent->_parent = SubL;if (parent == _root){SubL = _root;SubL->_parent = nullptr;}else{if (ppNode->_left == parent){ppNode->_left = SubL;}else if (ppNode->_right == parent){ppNode->_right = SubL;}SubL->_parant = ppNode;}
}

左旋代码

void RotateL(Node* parent)
{Node* SubR = parent->_right;Node* SubRL = SubR->_left;parent->_right = SubRL;if (SubRL)SubR->_parent = parent;SubR->_left = parent;Node* ppNode = parent->_parent;parent->_parent = SubR;if (parent == _root){SubR = _root;SubR->_parent = nullptr;}else{if (ppNode->_left == parent){ppNode->_left = SubR;}else if (ppNode->_right == parent){ppNode->_right = SubR;}SubR->_parant = ppNode;}
}

3.2 红黑树插入逻辑(重点)

typedef RBTreeNode<K, V>  Node;
public:bool Insert(const pair<K, V>& kv)
{if (_root == nullptr){_root = new Node(kv);return true;}Node* parent = nullptr;Node* cur = _root;while (cur){while (cur){if (cur->_kv.first < kv.first){parent = cur;cur = cur->_right;}else if (cur->_kv.first > kv.first){parent = cur;cur = cur->_left;}else{assert(!cur);}}//需要将这个节点连接起来cur = new Node(kv);cur->_color = RED;cur->_parent = parent;if (parent->kv.first > cur->_kv.first){parent->_left = cur;}else if (parent->kv.first < cur->_kv.first){parent->_right = cur;}//根据不同情况就行调整,父亲节点是黑色就是走到根了while (parent && parent->_color == RED){Node* grandfather = parent->_parent;//这里默认插入都是红色,这里需要进行调整if (parent == grandfather->_left){Node* uncle = grandfather->_right;if (uncle && uncle == RED){parent->_color = uncle->_color = BLACK;grandfather = RED;cur = grandfather;parent = cur->_parent;}//uncle不存在或者为黑色,需要旋转else{if (cur = parent->_left)//一边红的情况{RotateR(grandfather);parent->_color = BLACK;grandfather->_color = RED;}else{RotateL(parent);RotateR(grandfather);cur = BLACK;parent->_color = grandfather->_color = RED;}}}else{// 情况二:叔叔不存在或者存在且为黑// 旋转+变色//      g//   u     p//            cif (cur == parent->_right)//一边红的情况{RotateL(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{//		g//   u     p//      cRotateR(parent);RotateL(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}}//不管根是什么颜色,都修改一遍为黑色_root->_col = BLACK;return true;
}

四、遍历红黑树

如果中序遍历可得到一个有序的序列,就说明为二叉搜索树

void InOder()
{_InOder(_root);cout << endl;
}
private:	
void _InOder(Node* _root)
{_InOder(_root->_left);cout << endl;_InOder(_root->_right);}

这里将中序遍历实现逻辑封装到私有成员函数中隐藏它的具体实现细节,使得外部用户无法直接访问该函数,提高了代码的安全性和可维护性,符合面向对象编程的封装性原则。这里外部访问中序遍历接口,只是传递了节点指针的副本,而不修改任何节指针的实际值。

五、判断是否满足红黑树

可以根据红黑树的规则来进行判断,具体细节在代码块注释。其中规则四就是判断每条路径的黑色节点个数是否相同,那么可以提前记录好一条路径的黑色节点个数去比较,当_root == nullptr说明这条路径遍历完毕,需要就行判断

bool IsBalance() {//规则一:根节点颜色为黑色if (_root->_color == RED){return false;}int refNum = 0;//记录单独一边黑色节点个数Node* cur = _root;while (cur){refNum++;cur = cur->_left;}return Check(_root, 0, refNum);}
private:bool Check(Node* root, int blackNum, const int refNum)
{//接下就是遍历每条路径了if (_root == nullptr){//规则4if (blackNum != refNum){cout << "不满足每条路径相同黑色节点" << endl;return  false;}return true;}//规则3if (root->_col == RED && root->_parent->_col == RED){cout << root->_kv.first << "存在连续的红色节点" << endl;return false;}//记录每条路径的黑色节点//可行的原因是该blackNum传递形参//每个节点记录一个值:根到当前节点路径中黑色节点的数量if (root->_col == BLACK){blackNum++;}return Check(root->_left , blackNum,refNum) && Check(root->_right, blackNum, refNum)
}

关于规则3这里判断逻辑设计,是根找父亲,而不是根找儿子。如果是根找儿子,需要去左右孩子去找又分为多种情况,不然选择一条单一的路线,根找父亲,反正都是遍历每个节点。

在这里插入图片描述

问题:

  • 为什么不能通过其最长路径中节点个数不会超过最短路径节点个数的两倍来判断是否为红黑树呢?

答:

  • 这里是不充分必要条件,比如下图12左边这条路径不满足规则4,当插入时就会出现问题。(路径是指某条路径空节点到根节点)

在这里插入图片描述

六、红黑树的删除

红黑树的删除本节不做讲解,有兴趣的可参考:《算法导论》或者《STL源码剖析》。以下提供相关链接:红黑树删除

七、红黑树与AVL树的比较

红黑树和AVL树都是高效的平衡二叉树,增删改查的时间复杂度都是O(logn),红黑树不追求绝对平衡,其只需保证最长路径不超过最短路径的2倍,相对而言,降低了插入和旋转的次数,所以在经常进行增删的结构中性能比AVL树更优,而且红黑树实现比较简单,所以实际运用中红黑树更多

八、RBTree.h

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;enum Color
{RED, BLACK
};template<class K, class V>
struct RBTreeNode
{RBTreeNode<K, V>* _parent;RBTreeNode<K, V>* _left;RBTreeNode<K, V>* _right;pair<K, V> _kv;Color _color;RBTreeNode(const pair<K, V>& kv):_parent(nullptr), _left(nullptr), _right(nullptr), _kv(kv), _color(RED){}
};template<class K, class V>
class RBTree
{typedef RBTreeNode<K, V>  Node;
public:bool Insert(const pair<K, V>& kv){if (_root == nullptr){_root = new Node(kv);return true;}Node* parent = nullptr;Node* cur = _root;while (cur){while (cur){if (cur->_kv.first < kv.first){parent = cur;cur = cur->_right;}else if (cur->_kv.first > kv.first){parent = cur;cur = cur->_left;}else{assert(!cur);}}//需要将这个节点连接起来cur = new Node(kv);cur->_color = RED;cur->_parent = parent;if (parent->kv.first > cur->_kv.first){parent->_left = cur;}else if (parent->kv.first < cur->_kv.first){parent->_right = cur;}//根据不同情况就行调整,父亲节点是黑色就是走到根了while (parent && parent->_color == RED){Node* grandfather = parent->_parent;//这里默认插入都是红色,这里需要进行调整if (parent == grandfather->_left){Node* uncle = grandfather->_right;if (uncle && uncle == RED){parent->_color = uncle->_color = BLACK;grandfather = RED;cur = grandfather;parent = cur->_parent;}//uncle不存在或者为黑色,需要旋转else{if (cur = parent->_left){RotateR(grandfather);parent->_color = BLACK;grandfather->_color = RED;}else{RotateL(parent);RotateR(grandfather);cur = BLACK;parent->_color = grandfather->_color = RED;}}}else{// 情况二:叔叔不存在或者存在且为黑// 旋转+变色//      g//   u     p//            cif (cur == parent->_right){RotateL(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{//		g//   u     p//      cRotateR(parent);RotateL(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}}_root->_col = BLACK;return true;}void RotateR(Node* parent){Node* SubL = parent->_left;Node* SubLR = SubL->_right;parent->_left = SubLR;if (SubLR)SubLR->_parent = parent;SubL->_right = parent;Node* ppNode = parent->_parent;parent->_parent = SubL;if (parent == _root){SubL = _root;SubL->_parent = nullptr;}else{if (ppNode->_left == parent){ppNode->_left = SubL;}else if (ppNode->_right == parent){ppNode->_right = SubL;}SubL->_parant = ppNode;}}void RotateL(Node* parent){Node* SubR = parent->_right;Node* SubRL = SubR->_left;parent->_right = SubRL;if (SubRL)SubR->_parent = parent;SubR->_left = parent;Node* ppNode = parent->_parent;parent->_parent = SubR;if (parent == _root){SubR = _root;SubR->_parent = nullptr;}else{if (ppNode->_left == parent){ppNode->_left = SubR;}else if (ppNode->_right == parent){ppNode->_right = SubR;}SubR->_parant = ppNode;}}bool IsBalance(){if (_root->_color == RED){return false;}int refNum = 0;//记录单独一边黑色节点个数Node* cur = _root;while (cur){refNum++;cur = cur->_left;}return Check(_root, 0, refNum);}void InOder(){_InOder(_root);cout << endl;}private:bool Check(Node* root, int blackNum, const int refNum){//接下就是遍历每条路径了if (_root == nullptr){if (blackNum != refNum){cout << "不满足每条路径相同黑色节点" << endl;return  false;}return true;}if (root->_col == RED && root->_parent->_col == RED){cout << root->_kv.first << "存在连续的红色节点" << endl;return false;}if (root->_col == BLACK){blackNum++;}return Check(root->_left, blackNum, refNum) && Check(root->_right, blackNum, refNum)}void _InOder(Node* _root){_InOder(_root->_left);cout << endl;_InOder(_root->_right);}
private:Node* _root = nullptr;
};

在这里插入图片描述

感谢大家的观看!以上就是本篇文章的全部内容。我是店小二,希望这些高阶数据结构笔记能为你在学习旅途中提供帮助!

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

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

相关文章

Java使用HttpClient5实现发送HTTP请求

1、HttpClient5 的介绍 HttpClient5 是 Apache HttpComponents 项目中的一个重要组件&#xff0c;它是一个功能齐全且高度可定制的 HTTP 客户端库&#xff0c;专门用于发送 HTTP 请求、处理 HTTP 响应并支持各种 HTTP 协议特性。 以下是对 HttpClient5 的详细介绍&#xff1a…

部署Qwen2.5-7b大模型详解

部署Qwen2.5-7b大模型详解 本文参考教程&#xff1a;https://qwen.readthedocs.io/en/latest/getting_started/quickstart.html 下载模型 https://modelscope.cn/organization/qwen 搜索 qwen2.5-7b 可以看到它提供了六个模型&#xff0c;以满足不同的需求&#xff0c;从下…

【RoadRunner】自动驾驶模拟3D场景构建 | 软件简介与视角控制

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

【MATLAB代码,带TDOA数据导入】TDOA三维空间的位置(1主锚点、3副锚点),多个时间点、输出位置的坐标

TDOA介绍 TDOA&#xff08;到达时间差&#xff09;是一种用于定位和跟踪信号源的技术&#xff0c;常用于无线通信、导航和雷达系统。它通过测量信号到达不同接收器的时间差&#xff0c;来计算信号源的位置。 基本原理 TDOA的基本原理是利用多个接收器&#xff08;或锚点&…

Power BI - 设置Waterfall Chart第一个Pillar的颜色

1.简单介绍 有的用户可能会单独设置Column Chart&#xff08;条形图&#xff09;的第一个柱子的颜色&#xff0c;如下图所示&#xff0c; 这种其实可以通过Column Chart的Conditional formating进行设置&#xff0c; - SWICH SELECTEDVALUE 或者也可以直接对单独的Column进行…

用户界面设计:视觉美学与交互逻辑的融合

1、什么是用户界面 用户界面&#xff08;UI&#xff09;是人与机器之间沟通的桥梁&#xff0c;同时也是用户体验&#xff08;UX&#xff09;的重要组成部分。用户界面设计包括两个核心要素&#xff1a;视觉设计&#xff08;即产品的外观和感觉&#xff09;和交互设计&#xff…

CSS 入门

1. CSS 1.1 概念 CSS&#xff08;Cascading Style Sheet&#xff09;&#xff0c;层叠样式表&#xff0c;用于控制页面的样式 CSS 能够对网页中元素位置的排版进行像素级精确控制&#xff0c;实现美化页面的效果&#xff0c;能够做到页面的样式和结构分离&#xff08;类似于…

【数字图像处理】第5章 图像空域增强方法

上理考研周导师的哔哩哔哩频道 我在频道里讲课哦 目录 5.1 图像噪声 相关概念 ①图像噪声的产生 ② 图像噪声分类 ③ 图像噪声特点 5.2 图像增强方法分类 ①图像增强概念 ②图像增强目的 ③图像增强技术方法: 5.3 基于灰度变换的图像增强 1. 概述: 2. 灰度变换…

十大云手机排行榜:哪个云手机更好用?

近些年&#xff0c;市场上涌现出许多云手机产品&#xff0c;不同产品适合的应用场景也各不相同。在选用云手机之前&#xff0c;企业和个人用户需要了解它们的功能、特点以及适用的场景。本文将对当前主流的云手机进行对比&#xff0c;帮助大家挑选出最适合的云手机产品。 1. 红…

【数据结构与算法】之链表详解

链表是一种常用的数据结构&#xff0c;它是一种线性数据结构&#xff0c;但与数组不同&#xff0c;它并非连续存储数据&#xff0c;而是通过指针将数据节点连接起来。每个节点都包含数据域和指向下一个节点的指针域。这种结构赋予链表独特的优势和局限性&#xff0c;使其在某些…

九种排序,一次满足

我们在算法题进行练习提升时&#xff0c;经常会看到题目要求数据从大到小输出&#xff0c;从小到大输出&#xff0c;前一半从小到大输出&#xff0c;后一半从大到小输出等&#xff0c;那么这时候就需要用到排序算法&#xff0c;通过排序算法将数据按照一定的顺序进行排序。本文…

解决PyCharm 2023 Python Packages列表为空

原因是因为没有设置镜像源 展开 > 之后&#xff0c;这里 点击齿轮 添加一个阿里云的源 最后还需要点击刷新 可以选择下面的任意一个国内镜像源&#xff1a; 清华&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 阿里云&#xff1a;http://mirrors.aliyun.com/…

设计模式之-策略模式配合枚举

1、定义枚举接收不同的参数使用不同的handler, 2、定义个handerl接口&#xff0c;统一方法处理&#xff0c;每个handler实现该接口 public interface IMethodHandler<T, R> {/*** 处理统一入口** param req*/R process(T req); } java3、定义一个简单工厂统一处理 Comp…

送给正在入行的小白:最全最有用的网络安全学习路线已经安排上了,零基础入门到精通,收藏这一篇就够了

在这个圈子技术门类中&#xff0c;工作岗位主要有以下三个方向&#xff1a; 安全研发安全研究&#xff1a;二进制方向安全研究&#xff1a;网络渗透方向 下面逐一说明一下。 第一个方向&#xff1a;安全研发 你可以把网络安全理解成电商行业、教育行业等其他行业一样&#xf…

k8s 1.28.2 集群部署 harbor v2.11.1 接入 MinIO 对象存储

文章目录 [toc]提前准备什么是 HarborHarbor 架构描述Harbor 安装的先决条件硬件资源软件依赖端口依赖 Harbor 在 k8s 的高可用Harbor 部署Helm 编排YAML 编排创建 namespace导入镜像部署 Redis部署 PostgreSQL部署 Harbor core部署 Harbor trivy部署 Harbor jobservice部署 Ha…

RTSP流图片采样助手(yolov5)

在监控和视频分析领域&#xff0c;实时采样视频流中的图像数据是十分重要的。本文将介绍一个基于Python和Tkinter构建的RTSP流图片采样助手的设计与实现&#xff0c;旨在简化RTSP流的采样过程&#xff0c;并支持根据用户定义的特殊标签进行筛选。 项目概述 该项目的主要功能包…

Data+AI下的数据湖和湖仓一体发展史

DataAI下的数据湖和湖仓一体发展史 前言数据湖的“前世今生”AI时代的救星&#xff1a;湖仓一体湖仓一体实践演进未来趋势&#xff1a;智能化、实时化结语 前言 数据湖&#xff1f;湖仓一体&#xff1f;这是什么高科技新名词&#xff1f; 别急&#xff0c;我们慢慢聊。想象一…

ICT产业新征程:深度融合与高质量发展

在信息时代的浪潮中&#xff0c;每一场关于技术革新与产业融合的盛会都闪耀着智慧的光芒&#xff0c;引领着未来的方向。9月25日&#xff0c;北京国家会议中心内&#xff0c;一场聚焦全球信息通信业的顶级盛事——第32届“国际信息通信展”&#xff08;PT展&#xff09;隆重拉开…

Maven基于构建阶段分析多余的依赖

基于构建阶段 test compile 实现依赖分析 执行maven 命令: mvn dependency:analyze 关注:Maven-dependency-plugin 分析结果: [INFO] --- maven-dependency-plugin:2.10:analyze (default-cli) impl --- 配置依赖未使用的依赖项&#xff1a; [INFO] --- maven-dependency-…

Linux基础项目开发day2:量产工具——输入系统

文章目录 前言一、数据结构抽象1、数据本身2、设备本身3、input_manager.h 二、触摸屏编程1、touchscreen.c 三、触摸屏单元测试1、touchscreen.c2、上机测试 四、网络编程netiput.c 五、网络单元测试1、netiput.c2、client.c3、上机测试 六、输入系统的框架1、框架思路2、inpu…