在计算机科学和算法竞赛中,C++树直径算法是一个经典而实用的问题。所谓“树的直径”,指的是树中任意两个节点之间最长路径的长度(边数或节点数,通常指边数)。理解并掌握这一算法,不仅能帮助你解决图论问题,还能提升对深度优先搜索(DFS)和广度优先搜索(BFS)的理解。
树是一种无环连通无向图。树的直径就是这棵树中距离最远的两个节点之间的路径长度。例如,下面这棵树的直径是4(路径为 1-2-3-4-5):

求树的直径有多种方法,但最常用且高效的是两次BFS/DFS法。其核心思想如下:
这个方法的正确性基于树的性质:从任意点出发的最远点一定是直径的一个端点。
下面我们用C++实现上述算法。假设输入是一棵无向树,以邻接表形式存储。
#include <iostream>#include <vector>#include <queue>#include <algorithm>using namespace std;// BFS函数:返回 {最远节点, 最大距离}pair<int, int> bfs(int start, const vector<vector<int>>& graph) { int n = graph.size(); vector<int> dist(n, -1); queue<int> q; dist[start] = 0; q.push(start); while (!q.empty()) { int u = q.front(); q.pop(); for (int v : graph[u]) { if (dist[v] == -1) { dist[v] = dist[u] + 1; q.push(v); } } } // 找到距离最大的节点 int maxDist = 0, farthestNode = start; for (int i = 0; i < n; ++i) { if (dist[i] > maxDist) { maxDist = dist[i]; farthestNode = i; } } return {farthestNode, maxDist};}// 求树的直径int treeDiameter(const vector<vector<int>>& graph) { // 第一次BFS:从节点0出发找最远点A pair<int, int> first = bfs(0, graph); int nodeA = first.first; // 第二次BFS:从A出发找最远点B,此时的距离就是直径 pair<int, int> second = bfs(nodeA, graph); return second.second; // 返回直径长度(边数)}int main() { // 示例:构建一棵5个节点的树 // 边: 0-1, 1-2, 2-3, 3-4 int n = 5; vector<vector<int>> graph(n); // 添加无向边 auto addEdge = [&](int u, int v) { graph[u].push_back(v); graph[v].push_back(u); }; addEdge(0, 1); addEdge(1, 2); addEdge(2, 3); addEdge(3, 4); cout << "树的直径为: " << treeDiameter(graph) << endl; // 输出: 树的直径为: 4 return 0;}该算法执行了两次BFS,每次BFS的时间复杂度为O(V + E),其中V是节点数,E是边数。由于树满足E = V - 1,因此总时间复杂度为O(V)。空间复杂度也是O(V),用于存储图和距离数组。
如果你处理的是二叉树(每个节点最多有两个子节点),也可以用递归方式求直径。此时直径可能不经过根节点,需要记录每个节点的左右子树最大深度之和。
这种变体常出现在面试题中,属于二叉树直径求解的经典问题。
通过本文,我们学习了如何使用C++实现树的最长路径(即树的直径)的高效算法。无论是通用树还是二叉树,掌握这些技巧都能让你在算法竞赛或面试中游刃有余。记住,核心思想是“两次搜索找最远点”,这是解决C++图论算法中许多问题的关键思路。
希望这篇教程能帮助编程小白轻松入门树直径问题!动手写一遍代码,你会理解得更深刻。
本文由主机测评网于2025-12-04发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025122689.html