求树的“直径”以及所想到的
来源:互联网 发布:办公室小野 知乎 编辑:程序博客网 时间:2024/05/16 18:07
算法导论22.2-7题:树T=(V,E)的直径(diameter)定义为max(u,v),亦即,树的直径是树中所有最短路径长度中的最大值。试写出计算树的直径的有效算法,并分析算法的运行时间。
如果这里的树T是简单的二叉树或者多叉树,我们可以用递归来解决(Diameter(tree T)表示T的直径);
1. 求出T左子树的最深节点的深度Dleft,求出T右子树最深节点的深度Dright。
2. 则T的直径为:max(Dleft + Dright + 1, Diameter(T->left), Diameter(T->right))
这里使用递归是因为有可能直径不经过根节点。时间复杂度为O(n^2).
下面还有个优化方法,可以使得时间复杂度为O(n).
Optimized implementation: The above implementation can be optimized by calculating the height in the same recursion rather than calling a height() separately. Thanks to Amar for suggesting this optimized version. This optimization reduces time complexity to O(n).
- /*The second parameter is to store the height of tree.
- Initially, we need to pass a pointer to a location with value
- as 0. So, function should be used as follows:
- int height = 0;
- struct node *root = SomeFunctionToMakeTree();
- int diameter = diameterOpt(root, &height); */
- int diameterOpt(struct node *root, int* height)
- {
- /* lh --> Height of left subtree
- rh --> Height of right subtree */
- int lh = 0, rh = 0;
- /* ldiameter --> diameter of left subtree
- rdiameter --> Diameter of right subtree */
- int ldiameter = 0, rdiameter = 0;
- if(root == NULL)
- {
- *height = 0;
- return 0; /* diameter is also 0 */
- }
- /* Get the heights of left and right subtrees in lh and rh
- And store the returned values in ldiameter and ldiameter */
- ldiameter = diameterOpt(root->left, &lh);
- rdiameter = diameterOpt(root->right, &rh);
- /* Height of current node is max of heights of left and
- right subtrees plus 1*/
- *height = max(lh, rh) + 1;
- return max(lh + rh + 1, max(ldiameter, rdiameter));
- }
如果这里的树进化为了图,该如何求出它的直径呢?
1. 从任意一个节点u开始做第一遍BFS,得到距离u最远的那个节点v
2. 从节点v开始做第二遍BFS,得到距离v最远的节点 e, 那 v 到 e 就是直径。
证明:
1. 如果 u 在直径路径上:反证法, 如果v不在直径上,那根据直径的定义,必然存在一点v2在直径上,使得dist(u->v2) 大于 dist(u->v), 而这和BFS算法 v是从u 出发到达的所有节点中离u最远相矛盾。
2. 如果 u 不在直径路经上, 反证法,看图:
u ----- w ------- v
/
x ----------y ----------z
上图中,u-->v 是第一遍BFS算出来的路径,x-->z 是直径路径,反证法假设v 不在直径路径上,如图所示。根据树和联通图的定义,u->v中必然存在一点w, 和x->z中的某点y 相连通,或者说必然存在一个路径 w--y ,链接uv和xz。
代码就不写了,不是很复杂。- 求树的“直径”以及所想到的
- 求树的“直径”以及所想到的
- 求树的直径
- 求树的直径
- 求树的直径
- 求树的直径
- BFS求树的直径
- HDU4607(求树的直径)
- [toj3517]【求树的直径】
- 求树的直径证明
- hdu4607 (求树的直径)
- 求树的直径算法
- spfa求树的直径
- 求树的直径问题
- 无向图的直径以及树的直径
- 无向图的直径以及树的直径
- 无向图的直径以及树的直径
- 由二叉树反转所想到的
- 嵌入式逻辑分析仪SignalTap II 设计范例
- mybatis 类型类型转换器
- 第四次上机赛标程
- UDP
- c 实现的 循环队列
- 求树的“直径”以及所想到的
- hdu2604(矩阵快速幂)
- sybase用户创建及授权
- Java Collection interview Questions Answers | Java Collection FAQ
- 2014.5.23第一开通blog
- 理解Java的GC与引用
- c 实现IO流
- Python的动态加载机制
- HashMap泛型编程