二叉树也是一个图,虽然在一般的图中求解简单最长路径问题非常困难,但是在二叉树中却比较简单!我们甚至可以在线性时间内解决问题!
二叉树中距离最长的两个节点一定是叶子节点或根节点,假设有一个节点不是叶子节点或根节点,那么其父亲或者其儿子到另外一个节点的距离比最大距离要大,所以假设错误。如果距离最长的两个节点有一个是根,那么最长距离就等于树的高,而且根只有一个儿子,否则一定存在更长的距离。对于某一个节点,设其左儿子和右儿子的高度分别为ha和hb,如果其两个儿子没有距离大于ha+hb的路径,那么ha+hb就是以这个节点为根的树的最长距离。如果maxlen(i)表示以节点i为根的树的最大距离,那么maxlen(i) = max(max(maxlen(i的左子树),maxlen(i的右子树)),i左儿子的高度+i右儿子的高度)。
#include <iostream>
#include <string>
using namespace std;
struct tree {
int value;
int maxlen;
int height;
struct tree *lchild;
struct tree *rchild;
};
struct tree *gen(int v)
{
struct tree *root = new struct tree;
root->value = v;
root->maxlen = 0;
root->height = 0;
root->lchild = 0;
root->rchild = 0;
}
size_t maxlen(struct tree *root)
{
if (root) {
size_t lhi = 0, rhi = 0, llen = 0, rlen = 0;
maxlen(root->lchild);
maxlen(root->rchild);
if (root->lchild) {
lhi = root->lchild->height;
llen = root->lchild->maxlen;
}
if (root->rchild) {
rhi = root->rchild->height;
rlen = root->rchild->maxlen;
}
root->height = max(lhi, rhi) + 1;
root->maxlen = max(max(llen, rlen), lhi + rhi);
return root->maxlen;
}
return 0;
}
struct tree *rebuild_fm(string f, string m)
{
if (f.length() > 0 && f.length() == m.length()) {
size_t pos = m.find(f[0]);
if (pos != string::npos) {
string ff, mm;
struct tree *root = new struct tree;
root->value = m[pos];
root->maxlen = 0;
root->height = 0;
ff = f.substr(1, pos);
mm = m.substr(0, pos);
root->lchild = rebuild_fm(ff, mm);
ff = f.substr(pos+1, f.length()-pos-1);
mm = m.substr(pos+1, m.length()-pos-1);
root->rchild = rebuild_fm(ff, mm);
return root;
}
}
return 0;
}
int main()
{
struct tree *root = rebuild_fm(
"abdhcmrswyinotxzecfgjpquvk",
"chrmywsdnioxztbeafcpjuqvgk"
);
cout << maxlen(root) << endl;
}