算法题——二叉树中结点的最远距离

题目:给定一棵二叉树,结点的距离就是两个结点之间路径包含的结点的数目,求结点的最大距离。

可以参考这两篇文章:《编程之美: 求二叉树中节点的最大距离》的另一个解法 和 Tree Diameter

思路

在每一个结点处,求两个信息:以该结点为根的树的高度,以及以该结点为根的树中包含的最大距离。

因为所求的最大距离,如果是跨越根结点的,则为两个子树的树高度之和+1,如果是不跨越根结点的,则为左右子树中的最大距离的最大值。

代码

①参考第一篇文章,每次返回两个值:

 1 struct TreeNode
 2 {
 3     int val;
 4     TreeNode *left, *right;
 5 };
 6
 7 //每次返回两个值
 8 struct RetVal
 9 {
10     int height;
11     int max_dist;
12     RetVal(int h, int d): height(h), max_dist(d)
13     {
14     }
15 };
16
17 RetVal maxDistInTree(TreeNode *root)
18 {
19     if(root == NULL)
20         return RetVal(0, 0);
21
22     RetVal lcr = maxDistInTree(root->left); //left child result
23     RetVal rcr = maxDistInTree(root->right);
24
25     RetVal result;
26     result.height   = 1 +  max(lcr.height, rcr.height);
27     result.max_dist = max( max(lcr.max_dist, rcr.max_dist), lcr.height + rcr.height + 1 );
28
29     return result;
30 }

②参考第二篇文章,分别求高度和树直径

 1 //单独求高度和直径(最大距离)
 2 int treeHeight(TreeNode *root)
 3 {
 4     if(root == NULL)
 5     {
 6         return 0;
 7     }
 8     else
 9     {
10         return 1 + max( treeHeight(root->left), treeHeight(root->right) );
11     }
12 }
13
14 int treeDiam(TreeNode *root)
15 {
16     if(root == NULL)
17         return 0;
18
19     int l_height = treeHeight(root->left);
20     int r_height = treeHeight(root->right);
21
22     int l_diam   = treeDiam(root->left);
23     int r_diam   = treeDiam(root->right);
24
25     return max( max(l_diam, r_diam),
26                 l_height + r_height + 1);
27 }
时间: 2024-08-10 05:22:45

算法题——二叉树中结点的最远距离的相关文章

算法题——二叉树结点的中序遍历的后继结点

题目:给出二叉树的一个结点,返回它中序遍历顺序的下一个结点. 思路: 如果有指向父亲的结点,则: 如果当前结点有右儿子,或者当前结点是根结点,则后继结点为右子树的最左叶节点: 否则,如果当前结点是父结点的左儿子,则后继结点就是父结点:(其实是第三种情况的一个特例,即自己是第0代祖先,返回第一代祖先) 否则,向上遍历,直到n-1代祖先是n代祖先的左儿子,则后继结点为n代祖先:或者遍历到根节点后未找到符合的n代结点,则该结点为中序遍历的最后结点,没有后继. 时间复杂度为树的高度O(lgN). 代码:

经典白话算法之二叉树中序前序序列(或后序)求解树

这种题一般有二种形式,共同点是都已知中序序列.如果没有中序序列,是无法唯一确定一棵树的. <1>已知二叉树的前序序列和中序序列,求解树. 1.确定树的根节点.树根是当前树中所有元素在前序遍历中最先出现的元素. 2.求解树的子树.找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树.若根节点左边或右边为空,则该方向子树为空:若根节点 边和右边都为空,则根节点已经为叶子节点. 3.递归求解树.将左子树和右子树分别看成一棵二叉树,重复1.2.3步,直到所有的节点完成定

算法题——二叉树转换为左单链表

题目:给定一棵二叉树,将所有的结点都放到左儿子的位置,即除了root结点外,每一个结点都是其他某一个结点的左儿子.不用保持某种顺序,不能递归,O(1)空间. 思路: 我的想法是,维持一个遍历指针p,另一个指针tail永远指向向左遍历到底的结点: 初始化p和tail都为root,开始循环: 如果p为叶子结点,则退出循环: 如果p没有右儿子,则向左下降一层: 如果p有右儿子,则tail向左遍历到底,将p的右子树挂到tail的左儿子上,p右儿子赋空值,然后向左下降一层. p每次下降一层时,tail从上

算法题——二叉树转换为双向链表

1 BSTreeNode* ConvertNode(BSTreeNode* pNode, bool asRight) 2 { 3 if(!pNode) 4 return NULL; 5 6 BSTreeNode *pLeft = NULL; 7 BSTreeNode *pRight = NULL; 8 9 // Convert the left sub-tree 10 if(pNode->m_pLeft) 11 pLeft = ConvertNode(pNode->m_pLeft, false

数据结构开发(23):二叉树中结点的查找、插入、删除与清除操作

0.目录 1.二叉树中结点的查找操作 2.二叉树中结点的插入操作 3.二叉树中结点的删除操作 4.二叉树中结点的清除操作 5.小结 1.二叉树中结点的查找操作 查找的方式: 基于数据元素值的查找 BTreeNode<T>* find(const T& value) const 基于结点的查找 BTreeNode<T>* find(TreeNode<T>* node) const 树中数据元素和结点的查找: 基于数据元素值的查找: 定义功能:find(node,

二叉树进阶之求一棵二叉树中结点间最大距离

转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6618074.html 二叉树中的结点间距离:从结点A出发到达B,每个结点只能走一次,AB路径上的结点数就是AB间距离. 由于从一个结点出发时,只有两种方向可走:向上经过父节点到达它的兄弟子树:向下到达它自己的左右子树: 对于一个结点h为根的子树:假设现在从h左子树中最深的叶结点逐层向上走,一直走到h的左儿子,现在h.left有两种选择: 一是向上经过h,然后到达h的右子树向下走到最深叶结点: 二是从h.le

编程之美——3.8求二叉树中结点的最大距离(树,递归,动态规划)

<编程之美>读书笔记12: 3.8 求二叉树中节点的最大距离 问题: 如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数.写一个程序求一棵二叉树中相距最远的两个节点之间的距离. 实际上就是求树的直径.若采用“动态规划方法”思想,会将该问题分解成“具有最大距离两点间的路径是否经过根节点”两个子问题,然后再对这两个子问题求解判断.实际上,不必这么麻烦.距离最远的两点必然在以某个节点A为根的子树上,它们间的路径必然经过该子树的根节

数据结构 - 求二叉树中结点的最大距离(C++)

// ------BTreeMaxNodeLength.cpp------ #include <iostream> using namespace std; template <class T> struct BTNode { // 左孩子 BTNode<T> *lChild; // 右孩子 BTNode<T> *rChild; // 该结点的值 T data; // 左子树最长距离 int leftSubTreeMaxLength; // 右子树最长距离

第六十四课 二叉树中结点的删除与清除

BTree.h中添加删除操作: 1 #ifndef BTREE_H 2 #define BTREE_H 3 4 #include "Tree.h" 5 #include "BTreeNode.h" 6 #include "Exception.h" 7 #include "LinkQueue.h" 8 9 namespace DTLib 10 { 11 12 template < typename T > 13 cl