問題描述:
把在二叉樹中,從一個節點到另一個節點的需要經過的邊數,定義爲距離。
求一棵二叉樹中,距離最遠的兩個節點之間的距離是多少?
問題分析:
最遠的節點可能出現兩種情況:
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;
}