问题描述:
把在二叉树中,从一个节点到另一个节点的需要经过的边数,定义为距离。
求一棵二叉树中,距离最远的两个节点之间的距离是多少?
问题分析:
最远的节点可能出现两种情况:
1) 位于根节点下面两棵不同的子树上,例如节点C和D
2) 位于根节点下面同一棵子树上,例如节点 F 和 I,他们位于B子树上。
这样问题可以转化为求二叉树子树上的最远节点,根节点也可以看做是一棵特殊的子树。
1) 一个节点除了保存左右子树的指针外,还分别保存它左右子树中节点的最大的距离。
2) 如果是叶子节点,那么它左右子树的节点的最大距离都是 0。
3) 通过深度优先遍历,由叶子节点逐层向上计算距离,并更新子树的根节点的最大的左右子树的距离。
4) 同时使用全局变量保存最大距离的值。
5) 当深度变量完成后,可以得到整个树中最远的两个节点的距离。
一种动态规划的想法。
代码:
#include <iostream>
using namespace std;
typedef struct _node
{
int _max_left;
int _max_right;
int _data;
_node *_left;
_node *_right;
} node;
int nMax = 0;
void calc(node* pNode)
{
int nTmp = 0;
if (NULL == pNode)
return;
if (NULL == pNode->_left)
{
pNode->_max_left = 0;
}
else
{
calc(pNode->_left);
}
if (NULL == pNode->_right)
{
pNode->_max_right = 0;
}
else
{
calc(pNode->_right);
}
if (pNode->_left != NULL)
{
if (pNode->_left->_max_left > pNode->_left->_max_right)
{
pNode->_max_left = pNode->_left->_max_left+1;
}
else
{
pNode->_max_left = pNode->_left->_max_right+1;
}
}
if (pNode->_right != NULL)
{
if (pNode->_right->_max_left > pNode->_right->_max_right)
{
pNode->_max_right = pNode->_right->_max_left+1;
}
else
{
pNode->_max_right = pNode->_right->_max_right+1;
}
}
nTmp = pNode->_max_right + pNode->_max_left;
if (nTmp > nMax)
{
nMax = nTmp;
}
}
void construct_test1(node* &pRoot)
{
node* pNode = NULL;
node* pCurr = NULL;
pNode = new node;
pNode->_max_left = 0;
pNode->_max_right = 0;
pNode->_max = 0;
pNode->_left = NULL;
pNode->_right = NULL;
pRoot = pNode;
pNode = new node;
pNode->_max_left = 0;
pNode->_max_right = 0;
pNode->_max = 0;
pNode->_left = NULL;
pNode->_right = NULL;
pRoot->_left = pNode;
pNode = new node;
pNode->_max_left = 0;
pNode->_max_right = 0;
pNode->_max = 0;
pNode->_left = NULL;
pNode->_right = NULL;
pRoot->_right = pNode;
pCurr = pRoot->_left;
pNode = new node;
pNode->_max_left = 0;
pNode->_max_right = 0;
pNode->_max = 0;
pNode->_left = NULL;
pNode->_right = NULL;
pCurr->_left = pNode;
pNode = new node;
pNode->_max_left = 0;
pNode->_max_right = 0;
pNode->_max = 0;
pNode->_left = NULL;
pNode->_right = NULL;
pCurr->_right = pNode;
pCurr = pCurr->_left;
pNode = new node;
pNode->_max_left = 0;
pNode->_max_right = 0;
pNode->_max = 0;
pNode->_left = NULL;
pNode->_right = NULL;
pCurr->_left = pNode;
pCurr = pRoot->_right;
pNode = new node;
pNode->_max_left = 0;
pNode->_max_right = 0;
pNode->_max = 0;
pNode->_left = NULL;
pNode->_right = NULL;
pCurr->_right = pNode;
}
void construct_test2(node* &pRoot)
{
node* pNode = NULL;
node* pCurr = NULL;
pNode = new node;
pNode->_max_left = 0;
pNode->_max_right = 0;
pNode->_max = 0;
pNode->_left = NULL;
pNode->_right = NULL;
pRoot = pNode;
pNode = new node;
pNode->_max_left = 0;
pNode->_max_right = 0;
pNode->_max = 0;
pNode->_left = NULL;
pNode->_right = NULL;
pRoot->_left = pNode;
pNode = new node;
pNode->_max_left = 0;
pNode->_max_right = 0;
pNode->_max = 0;
pNode->_left = NULL;
pNode->_right = NULL;
pRoot->_right = pNode;
}
int main()
{
int i = 0;
node* pRoot = NULL;
construct_test1(pRoot);
calc(pRoot);
cout << "Test 1 : Max length: " << nMax << endl;
nMax = 0;
construct_test2(pRoot);
calc(pRoot);
cout << "Test 2 : Max length: " << nMax << endl;
cin >> i;
return 0;
}