今天中午的时候有人问了我一个问题:求二叉树中节点的最大距离。这是《编程之美》上的一个问题。
花了一中午的时间总算解决了这个问题,有一点是很明确的:如果把树看做是一个图的话,它必然是连通的,任一节点总有路径到其他任何节点,这个题目就是求这样最长的一条路径。距离最大的两个节点可能是一个在左子树,一个在右子树,也可能是在一个子树上。下面的图展示了这两种情况
我试着把这个问题转化一下:树中的每一个节点都是一颗子树的根,对于这棵子树而言,它左子树的高度是Lm,右子树的高度是Rm,求所有子树中(Lm + Rm)的最大值是多少?(虽然不知道这样的问题在实际生产中是否有意义,也许有吧),还是用图比较直观。
在图上标出了每个节点左子树的长度和右子树的长度,叶子节点的左右子树长度都是0。每个节点左子树的长度是左孩子的左子树长度和左孩子右子树长度中较长的那个再加1,,这句话比较绕,但是好理解,比如A->Lm = Max(B->Lm,B->Rm) + 1,这样很明了了吧。有了上面的信息之后,我们可以计算每棵子树的(Lm + Rm),其中最大者就是结果。由于树的定义是递归的,所以用递归的方式更容易编程。
算法步骤:
(1)初始化二叉树,并将每个节点Lm和Rm初始化为0,定义二叉树中节点的最大距离Max = -1
(2)为了计算一个节点的Lm和Rm,需要采用后序遍历策略,递归的计算出它左孩子Left的Lm,Rm,Lm = max(Left->Lm + Left->Rm) + 1;和右孩子Right的Lm,Rm,Rm = max(Right->Lm,Right->Rm) + 1;
(3)对于每一个节点,计算Lm + Rm,如果其值大于Max,则Max = Lm + Rm,最后Max就是最大距离。
树节点的声明如下:
typedef struct TreeNode *Position;
typedef Position Tree;
struct TreeNode {
int element;
Position left;
Position right;
int lm;
int rm;
};
static int max = -1;//保存最远的距离
实际算法如下:
/*计算一棵树中,距离最远两个节点之间的距离*/
/*具体算法:每个节点有两个域分别用来保存它左子树的最大高度lm和右子树的最大高度rm
*将lm + rm与当前已知最远的距离相比较,如果大于max,则更新Max的值
*/
int maxDist(Tree root) {
//如果树是空的,则返回0
if(root == NULL)
return 0;
if(root->left != NULL) {
root->lm = maxDist(root->left) + 1;
}
if(root->right != NULL)
root->rm = maxDist(root->right) + 1;
//如果以该节点为根的子树中有最大的距离,那就更新最大距离
int sum = root->rm + root->lm;
if(sum > max) {
max = sum;
}
return root->rm > root->lm ? root->rm : root->lm;
}
上面的代码对每个节点只处理一次,所以时间复杂度是O(N),N是节点个数。
转载请注明:喻红叶《求二叉树中节点的最大距离》
分享到:
相关推荐
在计算机科学中,二叉树是一种非常重要的数据结构,而求二叉树节点的最大距离是二叉树中一个经典的问题。问题的定义是这样的:在二叉树中,计算任意两个节点之间的最大路径长度,路径长度是指路径上的边数。解决这个...
在二叉树问题中,"二叉树中的两节点中的最大距离"是一个常见的算法问题,主要涉及图论和数据结构的领域。这个问题的目标是找到二叉树中任意两个节点之间的最长路径,其中路径的长度定义为节点之间的边的数量。解决这...
在上面的代码中,我们使用了递归函数creatbtree来建立二叉树。该函数将输入的字符作为树的结点,并递归地建立左子树和右子树。当输入的字符为“#”时,表示建立一颗空树。 在creatbtree函数中,我们首先读取输入的...
c语言实现寻找一个二叉树中距离最大的两个节点
12. **求二叉树中节点的最大距离**:需要找到最大路径的两个叶节点,可以通过层次遍历并维护最大距离。 13. **根据前序和中序遍历序列重建二叉树**:前序遍历的第一个元素是根节点,中序遍历中根节点的左侧是左子树...
12. **求二叉树中节点的最大距离**:需要遍历整个树,记录最大路径长度。 13. **由前序遍历序列和中序遍历序列重建二叉树**:根据前序遍历的第一个元素作为根节点,再根据中序遍历找到根节点的位置,从而划分左右...
同时,定义了顺序栈和循环队列的数据类型,用于处理二叉树节点,表明在实际编程中,这些数据结构和算法是处理树问题的关键工具。 总结来说,树和二叉树是数据结构的基础,它们在搜索、排序、表达复杂数据关系等方面...
深度是树中最远叶子节点到根节点的距离;结点总数包括所有内部节点和叶子节点;叶结点数是树中没有子节点的节点数。这些属性可以通过递归函数计算,例如,深度可通过递归地访问子树并取最大深度,结点数和叶结点数...
- **二叉树节点结构**:每个节点包含数据域、指向左子树的指针和指向右子树的指针。 - **递归实现**:大多数操作都采用递归的方式实现,这有助于简化代码并保持清晰度。 - **先序遍历**:先访问根节点,然后递归...
- **满二叉树**:除了最后一层外,每一层的节点数都达到最大,且所有节点都集中在最左边。 - **完全二叉树**:除了最后一层,其他层都是满的,最后一层的节点都集中在左边,这是二叉树中效率较高的一种结构。 #### ...
有两个子节点的节点,通常选择左子树的最大节点或者右子树的最小节点作为替代节点。 5. **遍历二叉树**:主要有三种遍历方式:前序遍历(根-左-右),中序遍历(左-根-右)和后序遍历(左-右-根)。这些遍历方法在...
在实际编程中,二叉树的遍历算法是解决问题的基础,例如在搜索最长字符串、计算二叉树的最大距离、重建二叉树、分层遍历二叉树等问题时都会用到。 此外,二叉树相关的知识还包括但不限于深度优先搜索(DFS)用于...
- **删除有两个子节点的节点**:此时较为复杂,通常的做法是找到待删除节点右子树中的最小节点(或者左子树中的最大节点),用它来替换待删除的节点,然后再删除这个最小(或最大)节点。 除了以上介绍的基本操作...
最后,输出的结果`sum+2`是因为直径是两个节点之间的距离,而在计算过程中我们只考虑了子树的直径,所以需要加上根节点到这两个节点的距离,即加2。 需要注意的是,该算法的时间复杂度是O(n^2),因为每个节点都被...
1. **根节点**:二叉树中唯一没有父节点的节点。 2. **度**:节点的子节点数量,如叶子节点的度为0,分支节点的度大于0。 3. **树的度**:树中所有节点度的最大值。 4. **路径**:从根节点到任意节点的路径,由一...
3. **二叉树的最大深度**:求二叉树的最大深度,即树中任意节点的最大距离。可以采用递归或栈辅助的非递归方法。 4. **对称二叉树**:判断一棵二叉树是否是对称的,即镜像的。可以使用递归方法,比较当前节点的左右...
代码首先定义了一个二叉树节点的结构体`BiTNode`,包含一个整数值`data`以及指向左右子节点的指针。接下来,`Depth`函数用于计算给定节点的深度,通过递归遍历左子树和右子树。主函数`main`初始化了二叉树,并使用...
- **完全二叉树**:若一棵二叉树的深度为 h,且除最后一层外,其余各层的节点数都达到最大值,而最后一层的节点都集中在该层的最左边,这样的二叉树被称为完全二叉树。 - **满二叉树**:所有非叶节点都具有两个子...
这道题的目标是计算树的所有层中最大的宽度,宽度定义为同一层中最左和最右非空节点之间的距离,包括中间的空节点。 **问题定义:** - 输入:一个二叉树的根节点 `root`。 - 输出:二叉树的最大宽度。答案需在32位...