问题:给定一棵二叉树(非二叉检索树),求二叉树中距离最远的两个叶子节点间的距离?其中两个叶子间的距离定义为:F(X,Y) = 从节点X到根节点路径上所有节点数据之和 + 从节点Y到根节点路径上所有节点数据之和 - 从X和Y的第一个祖先节点到根节点路径上所有节点数据之和。
该题的主要思路:
1.求出二叉树的所有叶子节点。
2.求任意两个叶子节点的第一个祖先节点。
3.计算具有祖先-子孙关系的两个节点之间的路径,并计算路径上节点数据之和。
#include <iostream>
#include <vector>
using namespace std;
struct Node
{
Node(int data_) {data = data_; left = NULL; right = NULL;}
int data;
Node* left;
Node* right;
};
bool isExistPath(Node* ancestor, Node* descendant, vector<Node*> &path, int &pathLen)
{
if(ancestor == NULL)
return false;
path.push_back(ancestor);
pathLen++;
if(ancestor->left == NULL && ancestor->right == NULL)
{
if(ancestor == descendant)
{
return true;
}
}
bool b1 = isExistPath(ancestor->left,descendant,path,pathLen);
bool b2 = isExistPath(ancestor->right,descendant,path,pathLen);
if(!b1 && !b2)
{
path.pop_back();
pathLen--;
return false;
}
return true;
}
int calculateDistance(Node* p, Node* q)
{
vector<Node*> path;
int pathLen = 0;
if(isExistPath(p,q,path,pathLen))
{
int res = 0;
for(int i = 0; i < pathLen; i++)
res += path[i]->data;
return res;
}
}
static vector<Node*> leafNodes;
void findLeafNodes(Node* root)
{
if(root->left == NULL && root->right == NULL)
leafNodes.push_back(root);
if(root->left)
findLeafNodes(root->left);
if(root->right)
findLeafNodes(root->right);
}
Node* LCA(Node* root, Node* p, Node* q) //least common ancestor
{
Node *l,*r,*tmp;
if(root == NULL)
return NULL;
if(root->left == p || root->left == q || root->right == p || root->right == q)
return root;
else
{
l = LCA(root->left,p,q);
r = LCA(root->right,p,q);
if(l != NULL && r != NULL)
return root;
else
{
tmp = (l != NULL) ? l : r;
return tmp;
}
}
}
int main()
{
Node* root = new Node(5);
root->left = new Node(4);
root->left->left = new Node(2);
root->left->right = new Node(1);
root->right = new Node(3);
root->right->left = new Node(6);
root->right->right = new Node(7);
root->right->right->left = new Node(8);
int res = 0;
int max = -1;
findLeafNodes(root);
for(int i = 0; i < leafNodes.size(); i++)
for(int j = i+1; j < leafNodes.size(); j++)
{
Node* lca = LCA(root,leafNodes[i],leafNodes[j]);
int d1 = calculateDistance(root,leafNodes[i]);
int d2 = calculateDistance(lca,leafNodes[j]);
res = d1 + d2 - lca->data;
max = res > max ? res : max;
}
cout << max << endl;
return 0;
}