转自:http://hi.baidu.com/xiangzifengshi/blog/item/06081a1b4302a6c5a6866944.html
求二叉树中节点的最大距离
《编程之美》3.8
解法:
考虑到二叉树本身具有递归结构,因此考虑递归求解。
考虑其中任意一个节点P,若P有左子树和右子树,那么,最大距离的两个节点可能出现下面的情况:两个都在左子树中,两个都在右子树种,一个在左子树中一个在右子树中(其中,一个是左子树中距离L最远的节点,一个是右子树中距离R中最远的节点。即:一个位于左子树中最深处,一个位于右子树中的最深处)。
设leftMaxDistance是左子树中的任意两个节点之间的最大距离;leftMaxDeep是左子树中任意一个节点在左子树中的最大深度;rightMaxDistance是右子树中的任意两个节点之间的最大距离;rightMaxDeep是右子树中任意一个节点在右子树中的最大深度。
那么,以节点P为根的树中,
maxDistance=max(leftMaxDistance,rightMaxDistance, leftMaxDeep+rightMaxDeep+1)
maxDeep=max(leftMaxDeep, rightMaxDeep)+1
因此,可以写出如下算法:
comMaxDistance(Node *p, maxDistance, maxDep)
if(p)
maxDistance=0
maxDeep=0
return
if(p->left == NULL && p->right==NULL)
maxDistance=0
maxDeep=1
return
leftMaxDistance=leftMaxDeep=0
comMaxDistance(p->left,leftMaxDistance, leftMaxDeep)
rightMaxDistance=rightMaxDeep=0
comMaxDistance(p->right, rightMaxDistance, rightMaxDeep)
maxDistance = max(leftMaxDistance, rightMaxDistance)
if(p->left && p->right)
maxDistance=max(maxDistance,leftMaxDeep+rightMaxDeep)
maxDeep=max(leftMaxDeep,rightMaxDeep)+1
else if(p->left)
maxDistance=max(maxDistance,leftMaxDeep)
maxDeep=leftMaxDeep+1
else
maxDistance=max(maxDistance,rightMaxDeep)
maxDeep=rightMaxDeep+1
该算法同时也是一种分治法。
代码:
#include <iostream>
using namespace std;
class Node{
public:
Node(char d):data(d), left(0), right(0){}
char data;
Node *left;
Node *right;
};
void comMaxDistance(Node *p, int &maxDistance, int &maxDeep){
if (!p)
{
maxDistance = 0;
maxDeep = 0;
return;
}
if (!p->left && !p->right)
{
maxDistance = 0;
maxDeep = 1;
return;
}
int leftMaxDistance, leftMaxDeep;
comMaxDistance(p->left, leftMaxDistance, leftMaxDeep);
int rightMaxDistance, rightMaxDeep;
comMaxDistance(p->right, rightMaxDistance, rightMaxDeep);
maxDistance = leftMaxDistance > rightMaxDistance ? leftMaxDistance : rightMaxDistance;
if (p->left && p->right){
maxDistance = maxDistance > (leftMaxDeep + rightMaxDeep) ? maxDistance : leftMaxDeep + rightMaxDeep;
maxDeep = leftMaxDeep > rightMaxDeep ? leftMaxDeep + 1 : rightMaxDeep + 1;
}
else if (p->left){
maxDistance = maxDistance > leftMaxDeep ? maxDistance : leftMaxDeep;
maxDeep = leftMaxDeep + 1;
}
else if (p->right)
{
maxDistance = maxDistance > rightMaxDeep ? maxDistance : rightMaxDeep ;
maxDeep = rightMaxDeep + 1;
}
}
int main(){
Node *pi = new Node('I');
Node *ph = new Node('H');
Node *pg = new Node('G');
Node *pf = new Node('F');
Node *pe = new Node('E');
Node *pd = new Node('D');
Node *pc = new Node('C');
Node *pb = new Node('B');
Node *pa = new Node('A');
/* pi->left = pg;
pi->right = ph;
pg->left = pc;
pg->right = pd;
ph->left = pe;
ph->right = pf;
pc->left = pa;
pe->right = pb;
Node *root = pi;*/
/* pi->right = ph;
ph->left = pf;
ph->right = pg;
pf->left = pc;
pg->left = pd;
pg->right = pe;
pc->left = pa;
pd->right = pb;
Node *root = pi;*/
pd->left = pc;
pd->right = pb;
pc->left = pa;
Node *root = pd;
int maxDistance, maxDeep;
comMaxDistance(root, maxDistance, maxDeep);
cout << maxDistance << endl;
return 0;
}