深入解析:数据结构 之 【图的遍历与最小生成树】(广度优先遍历算法、深度优先遍历算法、Kruskal算法、Prim算法实现)

news/2025/10/24 17:13:48/文章来源:https://www.cnblogs.com/lxjshuju/p/19163832

目录

1.图的遍历

1.1图的广度优先遍历

实现思路

代码呈现

广度优先遍历(BFS)详解与评价

1.2图的深度优先遍历

实现思路

递归实现

递归实现深度优先遍历(DFS)详解与评价

栈实现

栈实现DFS算法实现评价

2.最小生成树

2.1Kruskal算法

核心思想及演示

代码实现

Kruskal算法详解与评价

2.2Prim算法

核心思想及演示

代码实现

Prim算法详解与评价

3.上述总结

4. 底层数据结构分析

空间复杂度:稀疏图的天然适配

时间效率:遍历与边操作的优势


下述算法实现是在上一期邻接表实现图的代码基础上实现的

1.图的遍历

给定一个图G和其中任意一个顶点v0,从v0出发,沿着图中各边访问图中的所有顶点,且每个顶点仅被遍历一次。"遍历"即对结点进行某种操作的意思

1.1图的广度优先遍历

核心思想:从起点出发,先访问所有邻接顶点,再逐层向外扩展(类似水波纹扩散)

实现思路

(1)将给定起点入队列,并标记为入队列

(2)访问、出队头元素之后,将与队头元素相连的未被标记过的顶点入队列

(3)重复步骤2,直到队列为空为止

元素入队列就进行标记,那么就可以防止同一元素多次入队列

当出队头元素B时,与B相连的定点有A、C、E

A、C已经入队列了,就没有必要再入了

队列为空标志着给定起点所在的联通分量被遍历完

代码呈现

(1)实现铺垫:队列、标记数组

	void BFS(const V& src){int n = _vertexes.size();int srci = GetIndexOfVertexes(src);//队列和标记数组queue q;vector visited(n, false);//进队列就标记,防止同一元素多次入队列q.push(srci);visited[srci] = true;//..}

(2)遍历逻辑

    while (!q.empty()){//访问队头元素int front = q.front();q.pop();cout << front << " : " << _vertexes[front] << ' ';//所连接的未被访问过的顶点入队列Edge* cur = _tables[front];while (cur){if (visited[cur->_dsti] == false){q.push(cur->_dsti);visited[cur->_dsti] = true;}cur = cur->_next;}}

(1)队列不为空,说明还有顶点未被访问

(2)先访问队头元素(这里打印顶点下标及顶点)

(3)所连接的未被访问过的顶点入队列

  • 这里选择用邻接表查找未被访问过的顶点而不时邻接矩阵,是因为即使两顶点不相连,在遍历邻接矩阵的过程中也可能被访问,这就造成了效率损失(访问大量不存在的边时)

(4)直到队列为空,给定起点所在的联通分量被遍历完

(3)完整实现

//广度优先遍历
//从一个顶点出发,访问它所连接的未被访问过的顶点
void BFS(const V& src)
{int n = _vertexes.size();int srci = GetIndexOfVertexes(src);//队列和标记数组queue q;vector visited(n, false);//进队列就标记,防止同一元素多次入队列q.push(srci);visited[srci] = true;//每层的个数int levelsize = 1;//开始遍历while (!q.empty()){//一层一层的出for (int i = 0; i < levelsize; ++i){	//访问队头元素int front = q.front();q.pop();cout << front << " : " << _vertexes[front] << ' ';//所连接的未被访问过的顶点入队列Edge* cur = _tables[front];while (cur){if (visited[cur->_dsti] == false){q.push(cur->_dsti);visited[cur->_dsti] = true;}cur = cur->_next;}}cout << endl;levelsize = q.size();}
}

广度优先遍历(BFS)详解与评价

实现逻辑:基于队列实现,按层扩展访问范围。在邻接表中,通过队列管理顶点访问顺序,利用levelsize控制层序输出。
时间复杂度:O(V+E),与DFS相同但空间复杂度更高(队列需存储O(V)顶点)。
优点

  • 天然适合最短路径问题(如无权图)。
  • 层序遍历特性利于网络爬虫、社交网络层级扩散等场景。

缺点

  • 内存占用大(队列存储所有待访问顶点)。
  • 路径记录复杂(需额外存储父节点信息)。
    适用场景:无权图最短路径、网络爬虫、社交网络分析、连通分量检测。

1.2图的深度优先遍历

核心思想:从起点出发,沿着一条路径尽可能深地访问,直到无法继续(遇到已访问顶点或死胡同),然后回溯到上一个分支点继续探索

实现思路

(1)从给定起点出发,访问当前节点

(2)然后访问与当前节点相连的未被访问过的任一节点(一般是存储时的第一个点,访问过了就往后找)

(3)重复步骤2,直到与当前节点相连的节点都被访问过后,回溯到之前的某一节点

该节点的特点是:仍有相连的未被访问过的节点

(4)再从与该节点相连的未被访问过的任一节点出发,访问这任一节点

(5)重复步骤3,直到所有点都被访问过


访问A节点,B与A相连且未被访问                                                                                步骤1
访问B节点,E与B相连且未被访问                                                                                步骤2
访问E节点,G与E相连且未被访问                                                                                步骤2
访问G节点,与G节点相连的所有节点都被访问过,开始回溯G->E->B                        步骤3   
与B节点相连的C节点仍未被访问
访问C节点,F与C相连且未被访问                                                                                步骤4
访问F节点,D与F相连且未被访问                                                                                步骤2
访问D节点,与D节点相连的所有节点都被访问过,开始回溯D->F                               步骤3
与F节点相连的H节点仍未被访问
访问H节点,I与H相连且未被访问                                                                                步骤4
访问I节点,与I节点相连的所有节点都被访问过,开始回溯I->H->F->C->B->A           步骤3    
直到所有点都被访问过,遍历结束
递归实现

(1)求给定顶点的下标、创建标记数组,调用子函数

void DFS(const V& src)
{int n = _vertexes.size();int srci = GetIndexOfVertexes(src);vector visited(n, false);_DFS(srci, visited);
}

(2)子函数

void _DFS(int srci, vector& visited)
{//访问并标记cout << srci << " : " << _vertexes[srci] << endl;visited[srci] = true;//访问下一个相连但未访问过Edge* cur = _tables[srci];while (cur){if (visited[cur->_dsti] == false)_DFS(cur->_dsti, visited);cur = cur->_next;}
}

(1)访问当前节点并标记

(2)访问与当前节点相连但未访问过的顶点

  • 选择用邻接表查找未被访问过的顶点而不是邻接矩阵,这是因为矩阵有大量不存在的边时,在遍历邻接矩阵的过程会就造成了效率损失(访问大量不存在的边)

(3)完整呈现

		//栈溢出风险void DFS(const V& src){int n = _vertexes.size();int srci = GetIndexOfVertexes(src);vector visited(n, false);_DFS(srci, visited);}void _DFS(int srci, vector& visited){//立即访问并标记cout << srci << " : " << _vertexes[srci] << endl;visited[srci] = true;//访问下一个相连但未访问过Edge* cur = _tables[srci];while (cur){if (visited[cur->_dsti] == false)_DFS(cur->_dsti, visited);cur = cur->_next;}}
递归实现深度优先遍历(DFS)详解与评价

实现逻辑:基于递归/栈实现,从起点出发沿一条路径深入探索,直到无法前进时回溯。在邻接表结构中,通过_DFS函数递归访问相邻顶点,利用visited数组避免重复访问。

时间复杂度:O(V+E)(顶点数+边数),每个顶点和边各访问一次。

优点

  • 空间效率高(递归深度仅需O(V)),适合树或深度较大的图。
  • 路径探索直观,适合寻找连通分量、拓扑排序等。

缺点

  • 递归可能导致栈溢出(如代码中_DFS的栈深度风险)。
  • 非最优路径搜索(如最短路径需结合BFS)。
  • 适用场景:连通性检测、迷宫问题、拓扑排序、强连通分量。
栈实现

(1)给定起点入栈并标记,初始化标记数组

void DFS(const V& src)
{int n = _vertexes.size();int srci = GetIndexOfVertexes(src);stack st;stack tmp;//临时栈vector visited(n, false);//入栈就标记,防止同一元素多次入栈st.push(srci);visited[srci] = true;//遍历
}

(2)

while (!st.empty())
{//访问栈顶元素int top = st.top();st.pop();cout << top << ":" << _vertexes[top] << endl;//关联的未访问过的顶点全入栈Edge* cur = _tables[top];while (cur){if (visited[cur->_dsti] == false){tmp.push(cur->_dsti);}cur = cur->_next;}//逆序入栈,与递归访问顺序一致while (!tmp.empty()){int top = tmp.top();tmp.pop();visited[top] = true;st.push(top);}
}

(1)访问栈顶元素并出栈

(2)与栈顶元素相连的未被标记的元素全部入临时栈

(3)临时栈中元素导入栈中

(4)重复步骤123,直到栈中元素为空,遍历结束

  • 实现过程

  • 临时栈是为了倒腾顶点,调整访问顺序与递归访问时顺序一致
栈实现DFS算法实现评价

正确性:该DFS实现逻辑严谨,通过双栈机制(主栈st+临时栈tmp)实现了与递归DFS完全一致的深度优先访问顺序。关键优化点在于:

  • 使用tmp栈反转邻接顶点顺序,确保主栈st的弹出顺序符合深度优先特性(如邻接表存储A→B→C时,实际访问顺序为C→B→A)。
  • 入栈时立即标记visited,避免重复访问,时间复杂度严格为O(V+E)(V顶点数,E边数)。

潜在问题

  • 不连通图处理缺失:仅能遍历起始顶点所在连通分量,需外层补充循环处理多连通分量(如for(v∈V) if(!visited[v]) DFS(v))。
  • 顶点输出顺序:当前实现按访问顺序输出顶点,若需路径记录需额外存储父节点关系(如parent数组)

2.最小生成树

连通图中的每一棵生成树,都是原图的一个极大无环子图

即:从其中删去任何一条边,生成树 就不再连通;反之,在其中引入任何一条新边,都会形成一条回路。 若连通图由n个顶点组成,则其生成树必含n个顶点和n-1条边。

因此构造最小生成树的准则有三 条:

  • 1. 只能使用图中的边来构造最小生成树
  • 2. 只能使用恰好n-1条边来连接图中的n个顶点
  • 3. 选用的n-1条边不能构成回路

构造最小生成树的方法:Kruskal算法和Prim算法。这两个算法都采用了逐步求解的贪心策略。

  • 贪心算法:是指在问题求解时,总是做出当前看起来最好的选择。也就是说贪心算法做出的不是 整体 最优的的选择,而是某种意义上的局部最优解。贪心算法不是对所有的问题都能得到整体最优 解。

2.1Kruskal算法

核心思想及演示

核心思想:按边的权值从小到大排序,依次选择权值最小且不形成环的边,直到生成树包含所有顶点

代码实现

(1)最小生成树是图的子图,拥有与图相同的顶点

typedef graph self;

(2)使用优先级队列存储边,就可以依次选择权值最小的边

(3)使用并查集,进入最小生成树的顶点在同一个集合当中

W Kruskal(self& minTree)
{int n = _vertexes.size();minTree._index = _index;minTree._vertexes = _vertexes;minTree._tables.resize(n, nullptr);//优先级队列存储边priority_queue, greater> minpq;for (int i = 0; i < _tables.size(); ++i){//无向图的邻接表中,边存了双份Edge* cur = _tables[i];while (cur){minpq.push(*cur);cur = cur->_next;}}UnionFindSet ufs(n);//权值和、边数W totalw = W();int size = 0;//开始选边
}

(4)开始选边

//开始选边
while (!minpq.empty())
{//选出最小边Edge min = minpq.top();minpq.pop();//判环if (ufs.InSet(min._srci, min._dsti)){cout << "构成环:" << _vertexes[min._srci] << "->" << _vertexes[min._dsti]<< ":" << min._w << endl;continue;}//进入最小生成树minTree._AddEdge(min._srci, min._dsti, min._w);cout << _vertexes[min._srci] << "->" << _vertexes[min._dsti]<< ":" << min._w << endl;//进入最小生成树的顶点在同一个集合ufs.Union(min._srci, min._dsti);++size;totalw += min._w;if (size == n - 1)break;
}
if (size == n - 1)return totalw;
else return W();

(1)优先级队列不为空,就继续选边

(2)当前权值最小的边的两个顶点不能在并查集中,否则就会构成环

(3)当前权值最小的边的两个顶点不在并查集中,该边就进入最小生成树

(4)更新并查集、边数、权值和

(5)选够n - 1条边就跳出循环

(6)根据边数返回值

完整实现

//开始选边
while (!minpq.empty())
{//选出最小边Edge min = minpq.top();minpq.pop();//判环if (ufs.InSet(min._srci, min._dsti)){cout << "构成环:" << _vertexes[min._srci] << "->" << _vertexes[min._dsti]<< ":" << min._w << endl;continue;}//进入最小生成树minTree._AddEdge(min._srci, min._dsti, min._w);cout << _vertexes[min._srci] << "->" << _vertexes[min._dsti]<< ":" << min._w << endl;//进入最小生成树的顶点在同一个集合ufs.Union(min._srci, min._dsti);++size;totalw += min._w;if (size == n - 1)break;
}
if (size == n - 1)return totalw;
else return W();

Kruskal算法详解与评价

实现逻辑:贪心策略+并查集判环。将所有边按权重升序排序,逐个添加边到最小生成树(MST),通过并查集检测环。代码中priority_queue存储边,UnionFindSet实现连通性判断。
时间复杂度:O(E log E)(排序耗时),并查集操作近似O(α(V))。

空间复杂度

  1. 核心数据结构
  2. 优先队列(最小堆):存储所有边,空间复杂度O(E)
  3. 并查集:存储顶点集合关系,空间复杂度O(V)(父指针数组+秩数组)。
  4. 最小生成树存储:邻接表需O(V+E)空间(顶点+边)。
  5. 辅助空间visited数组O(V),临时变量O(1)
  6. 总空间复杂度O(E + V)
  7. (边排序占主导,适合稀疏图E≪V²)

优点

  • 适合稀疏图(边数远小于顶点数平方)。
  • 算法逻辑清晰,易于实现分布式计算。

缺点

  • 需存储所有边并排序,空间开销大。
  • 并查集实现复杂度影响性能(路径压缩可优化)。
    适用场景:稀疏图的最小生成树、网络规划、电路设计

2.2Prim算法

核心思想及演示

核心思想:从一个顶点开始,逐步扩展生成树,每次选择连接树内顶点树外顶点最小权值边

代码实现

(1)最小生成树是图的子图,拥有与图相同的顶点

typedef graph self;

(2)使用标记容器,区分树内与树外的顶点

(3)使用优先级队列存储边,就可以依次选择从树内顶点到树外顶点中权值最小的边

W Prim(self& minTree, const V& src)
{int srci = GetIndexOfVertexes(src);int n = _vertexes.size();minTree._index = _index;minTree._vertexes = _vertexes;minTree._tables.resize(n, nullptr);//在最小生成树中的顶点vector in(n, false);in[srci] = true;//优先级队列存储边priority_queue, greater> minpq;//从当前节点连接出去的边//无向图的邻接表中Edge* cur = _tables[srci];while (cur){minpq.push(*cur);cur = cur->_next;}//权值、边数W totalw = W();int size = 0;//开始选边
]

(2)开始选边

//开始选边
while (!minpq.empty())
{//选出最小边Edge min = minpq.top();minpq.pop();//判环if (in[min._dsti] == true){cout << "构成环:" << _vertexes[min._srci] << "->" << _vertexes[min._dsti]<< ":" << min._w << endl;continue;}//进入最小生成树minTree._AddEdge(min._srci, min._dsti, min._w);cout << _vertexes[min._srci] << "->" << _vertexes[min._dsti]<< ":" << min._w << endl;//进入最小生成树的顶点in[min._dsti] = true;++size;totalw += min._w;if (size == n - 1)break;//先做上述判断,再持续进边Edge* cur = _tables[min._dsti];while (cur){//边的顶点不再最小生成树内if(in[cur->_dsti] == false)minpq.push(*cur);cur = cur->_next;}
}
if (size == n - 1)return totalw;
else return W();

(1)优先级队列不为空,就继续选边

(2)当前权值最小的边的尾顶点不能在树中,否则就会构成环

  • 仅需判断边的尾节点,因为优先级队列中的边的头节点都在最小生成树中

(3)当前权值最小的边的尾顶点不在树中,该边就进入最小生成树

(4)更新标记数组、边数、权值和

(5)选够n - 1条边就跳出循环,否则将以当前边的尾节点为头节点的边入优先级队列

(6)根据边数返回值

Prim算法详解与评价

实现逻辑:从起点扩展,逐步连接新顶点。维护优先队列存储候选边,每次选择最小边连接已选顶点和未选顶点。代码中priority_queue动态更新候选边,in数组标记已选顶点。
时间复杂度:O(E log V)(优先队列操作),稠密图下优于Kruskal。

空间复杂度:

  1. 核心数据结构
  2. 优先队列(最小堆):动态存储候选边,最坏情况O(E)(每条边可能被插入一次)。
  3. 标记数组in[]:记录顶点是否在生成树中,空间O(V)
  4. 最小生成树存储:邻接表需O(V+E)空间。
  5. 辅助空间:邻接表遍历指针O(1),临时变量O(1)
  6. 总空间复杂度O(E + V)
  7. (优先队列占主导,适合稠密图E≈V²)

优点

  • 适合稠密图(边数接近顶点数平方)。
  • 无需全局排序,动态维护候选边更高效。

缺点

  • 优先队列实现复杂(如斐波那契堆可优化但代码复杂)。
  • 初始顶点选择影响收敛速度。
    适用场景:稠密图的最小生成树、图像分割、聚类分析。

3.上述总结

4. 底层数据结构分析

在图的遍历与最小生成树算法(如DFS、Kruskal、Prim)中,选择邻接表而非邻接矩阵作为底层数据结构可以从时空复杂度来分析

空间复杂度:稀疏图的天然适配

  • 邻接矩阵:空间复杂度为O(V²)(V为顶点数),无论图的稀疏或稠密,均需分配固定大小的二维数组。例如,1000个顶点的图需存储10⁶个元素,即使实际边数仅100条。
  • 邻接表:空间复杂度为O(V+E)(E为边数),仅存储实际存在的边。稀疏图(E≪V²)中优势显著,如1000顶点、1000边的图仅需约2000个存储单元(顶点+边),远优于邻接矩阵的百万级开销。
  • 适用场景:现实网络(如社交网络、交通网络)多为稀疏图,邻接表的空间经济性使其成为首选。

时间效率:遍历与边操作的优势

  • DFS的邻接顶点遍历
    • 邻接表:遍历顶点v的所有邻接顶点需O(deg(v))时间(deg(v)为v的度数),总时间复杂度O(V+E),与图结构自然匹配。
    • 邻接矩阵:需遍历v的整行(或列),耗时O(V),即使实际邻接顶点极少(如度数为10),导致总时间O(V²),效率低下。
  • Kruskal的边处理
    • 邻接表:可高效遍历所有边(如通过链表或迭代器),时间O(E),便于排序或插入优先队列。
    • 邻接矩阵:需双层循环遍历矩阵(O(V²)),提取边集的耗时占主导,尤其在稀疏图中劣势明显。
  • Prim的边选择
    • 邻接表:可快速访问顶点v的邻接边(O(deg(v))),便于动态更新优先队列。
    • 邻接矩阵:访问v的邻接边需O(V)时间,影响优先队列的更新效率。

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

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

相关文章

完整教程:构建并运行最小 Linux 内核

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

word批量转pdf

方法:使用Microsoft Word批处理宏 批量实现Word转PDF功能,适合办公人员。无需安装额外软件,操作简单,原生支持。 (1)打开任意 Word 文档,按下 Alt + F11 打开 VBA 编辑器(点击“开发工具”,点击“visual Basi…

【SAE出版 | 高届数 | 检索稳定】第七届土木建筑与城市工程国际学术会议(ICCAUE 2025)

第七届土木建筑与城市工程国际学术会议(ICCAUE 2025)将于2025年10月31日-11月2日在中国贵阳召开。【天津大学、中交天津港湾工程研究院有限公司主办!】 【高届数土木会议 | SAE出版,检索稳定!】 第七届土木建筑与…

qcefview库的使用

目录背景运行环境qcefview源码阅读代码目录代码结构列举的通讯方式通讯方式一,widget中的函数通知web页面改变通讯方式二、鼠标拖拽事件通讯方式三、c++中invoke函数响应(两种UrlRequest、QueryRequest)QCefView中定…

解决Qt 不能debug问题

排查思路 1. 工程配置 通过deepseek查询得到编译选项需要+g,如下 CONFIG += debug QMAKE_CXXFLAGS += -g QMAKE_LFLAGS += -g 1.1. 排查系统的gdb文件是哪个,看是不是期望和和编译配置应用的编译器配套 ----如,都使…

2025年项目总延期?这30款项目进度管理软件让我提前交付率85%!

项目总延期是困扰团队效率的常见难题,但选对工具能让交付率提升至85%以上。本文将为您精选30款高效的项目进度管理软件,覆盖从敏捷开发到传统瀑布模型的不同需求。无论是禅道的全流程管控、Jira的敏捷适配性,还是Tr…

2025 年最新护眼灯生产厂家推荐榜:含全光谱智能照明标杆企业及高产能品牌优选指南自然光护眼/全光谱护眼/儿童护眼吸顶灯公司推荐

引言 当下,电子设备普及让人们日均用眼时长远超以往,护眼照明需求急剧攀升,但护眼灯市场乱象却让消费者陷入困境。众多产品仅靠 “护眼” 噱头吸引购买,实际在光谱连续性、防蓝光效果、频闪控制等核心指标上未达健…

Exadata数据库性能异常,备份进程卡住

1、案例概述 某客户有一台Exadata X9M-2,据客户反馈:“晚上20:30分,开始expdp备份,20:32分卡住。同时,在20:30分也发起了RMAN备份,RMAN备份在21:44也卡住。之后,杀掉进程,并重启恢复正常。” 现在,客户希望分…

做本地门户网站 10 年,我靠微擎摆脱了 “客户需求五花八门” 的噩梦

在我们这座三线城市,我经营的 “小城网” 算小有名气 —— 做了 10 年本地门户网站,从最初帮商家挂广告,到后来承接小程序、公众号开发,手里攒了 200 多个本地客户。可这两年,我却越来越怕接客户的电话,不是不想…

2025 年国内吸顶灯源头厂家最新推荐排行榜:聚焦全光谱技术与品质生产,精选优质厂家助力家居照明选购全光谱/中山现代/客厅现代/吊灯吸顶灯公司推荐

引言 当前家居照明市场中,吸顶灯因适配场景广、照明效果稳定成为众多家庭首选,但市场乱象却给消费者选购带来极大困扰。一方面,品牌数量繁杂且质量差距悬殊,部分小厂家使用劣质材料生产,导致产品存在寿命短、光效…

RabbitMQ框架及应用场景

简介 RabbitMQ是一个使用Erlang,基于AMQP协议的MQ组件。 AMQP全称为 Advanced Message Queuing Protocol(高级消息队列协议****),是一个面向消息的中间件传输协议,用于在应用程序之间进行异步消息通信。 AMQP协议…

UNIX下C语言编程与实践11-UNIX 动态库显式调用:dlopen、dlsym、dlerror、dlclose 函数的使用与实例 - 指南

UNIX下C语言编程与实践11-UNIX 动态库显式调用:dlopen、dlsym、dlerror、dlclose 函数的使用与实例 - 指南2025-10-24 16:56 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: …

熟知大模型中mcp概念 --by zk

MCP核心概念解析 什么是MCP:让大模型拥有“手和脚” 大模型本身只有对话和决策能力,没有执行调用工具,获取资源的能力。因此定义一套让大模型调用外部能力的通用协议很重要。MCP(Model Context Protocol)是一套让…

【开题答辩全过程】以 “辛巴克餐饮”小程序为例,具备答辩的问题和答案

【开题答辩全过程】以 “辛巴克餐饮”小程序为例,具备答辩的问题和答案pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: …

2025年一体化雨水提升泵站厂家权威推荐榜单:污水提升泵站/一体化污水泵站/一体化雨水泵站源头厂家精选

在市政排水与水资源管理领域,一体化雨水提升泵站已成为现代城市基础设施的核心组成部分,其高效性能直接关系到城市防洪排涝能力与水环境保护质量。 随着全球城市化进程加速,市政排水系统面临前所未有的压力。据最新…

STM32软件I2C读写AT24C64 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

bcc

bcc原理从内核中获取数据。 整个工具的核心原理是利用 eBPF 技术,在内核中与块设备 I/O 相关的关键函数上设置探针(Tracepoint),从而在几乎无开销的情况下捕获 I/O 请求的开始和结束时间,计算出延迟,并将结果存入…

手写ibatis

通用 Mapper:提供通用的 CRUD 方法。条件构造器:支持链式调用,构建查询条件。分页查询:支持 Oracle 的分页查询。连表查询:支持 JOIN 查询。指定字段查询:支持动态选择查询字段。注解支持:通过注解配置实体类和…

读书笔记:解锁数据库查询新姿势:函数索引让你的搜索又快又准

我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢! 由于博客中有大量代码,通过页面浏览效果更佳。本文为个人学…

国产IPD项目管理软件推荐|别再靠 Excel 推 IPD 了!帮你把IPD流程从“纸上”搬进系统

本文盘点了国内能真正支撑 IPD 流程落地的几款软件,从配置灵活、可视化程度高的飞书项目,到深度面向研发的禅道,覆盖制造业、硬件、互联网等多场景。看完你就能判断:哪一款最适合你的组织,帮你实现从立项到评审、…