您的位置:首页 > 编程语言

《编程之美》——求二叉树中节点的最大距离

2015-11-12 15:47 405 查看
题:

如果把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义”距离”为两个节点之间的个数。

写一个程序求一棵二叉树中相距最远的两个节点之间的距离。

如下图所示,粗箭头的边表示最长距离:



分析与解法:

把所有节点的左子树的深度和右子树的深度都计算出来,这样每个节点的最大长度也就是左子树的深度加上右子树的深度。遍历所有的节点,找到最大长度。时间复杂度为O(n)。

代码如下:

typedef struct Node
{
struct Node *pLeft;     //左孩子
struct Node *pRight;    //右孩子
int maxLeftLen;         //左子树最长距离
int maxRightLen;        //右子树最长距离
char value;             //节点的值
}BiNode, *BiTree;

int maxLen = 0;

void findMaxLen(BiTree *root)
{
//遍历到叶子节点,返回
if(root == NULL)
return;

//若左子树为空,那么该节点左边最长距离为0
if(root -> pLeft == NULL)
root -> maxLeftLen = 0;

//若右子树为空,那么该节点右边最长距离为0
if(root -> pRight == NULL)
root -> maxRightLen = 0;

//若左子树非空,递归寻找左子树的最长距离
if(root -> pLeft != NULL)
findMaxLen(root -> pLeft);

//若右子树非空,递归寻找右子树的最长距离
if(root -> pRight != NULL)
findMaxLen(root -> pRight);

//计算左子树的最长节点距离
if(root -> pLeft != NULL)
{

int tempLen = 0;//记录左子树左右两边最大距离中的较大值

if(root -> pLeft -> maxLeftLen > root -> pLeft -> maxRightLen)
tempLen = root -> pLeft -> maxLeftLen;
else
tempLen = root -> pLeft -> maxRightLen;

root -> maxLeftLen = tempLen + 1;//得出左子树的最长节点距离
}

//计算右子树的最长节点距离
if(root -> pRight != NULL)
{
int tempLen = 0;

if(root -> pRight -> maxLeftLen > root -> pRight -> maxRightLen)
tempLen = root -> pRight -> maxLeftLen;
else
tempLen = root -> pRight -> maxRightLen;

root -> maxRightLen = tempLen + 1;
}

//更新最长距离
if(root -> maxLeftLen + root -> maxRightLen > maxLen)
maxLen = root -> maxLeftLen + root -> maxRightLen;
}


该解法的缺陷,及优化的另一种解法:

http://www.cnblogs.com/miloyip/archive/2010/02/25/1673114.html

树的直径(Diameter)是指树上的最长简单路径长度。

直径的求法:两遍BFS (or DFS)。

任选一点u为起点,对树进行BFS遍历,找出离u最远的点v

以v为起点,再进行BFS遍历,找出离v最远的点w。则v到w的路径长度即为树的直径。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: