面试题:求二叉树中节点的最大距离

来源:互联网 发布:唱歌学英语软件 编辑:程序博客网 时间:2024/05/21 17:41
如果我们把二叉树看成一个图,
父子节点之间的连线看成是双向的,
我们姑且定义"距离"为两节点之间边的个数。
写一个程序,

求一棵二叉树中相距最远的两个节点之间的距离。


解题思路:这是一道经典的树形DP的问题,两次遍历整棵树,一次从叶子到树根,求得以该点为根的树中节点到该点的最远距离,第二次从根到叶子进行遍历,因为每一个点到其它点的最远距离不一定在以该点为根的树中,可能在父节点的其它分支中,因此可以更新父节点到当前点的最远距离,然后比较每条分支的最远距离即可求得当前点的最远距离,这样便可以求出最后结果

参考代码如下:

#include <iostream>#include <string.h>using namespace std;#define maxn 0x3ffffffint max1;struct node{int num;            //二叉树中该节点的值int longest_val;    //以该节点为根离子树中的最大距离 int second_val;     //以该节点为根离子树中的第二大距离int father_val;     //经过该节点的父节点的最大距离        node *dp1;          //用来标记是否是以该节点为根离子树中的最大距离中的子树node *left;node *right;};int max(int a,int b){return a>b?a:b;}void newset(node *&s,int N)      //建立二叉树{if(s==NULL){node *Node=new node();Node->longest_val=0;Node->second_val=0;Node->num=N;Node->left=NULL;Node->right=NULL;Node->dp1=NULL;s=Node;}else if(s->num<N){newset(s->right,N);}else if(s->num>N){newset(s->left,N);}}void dfs1(node *&s)       //进行第一次深搜,求得以该点为根的树中节点到该点的最远距离{if(s->left!=NULL){dfs1(s->left);node *next=s->left;if(s->longest_val<next->longest_val+1)          {              s->longest_val=next->longest_val+1;              s->dp1=next;          }  }if(s->right!=NULL){dfs1(s->right);node *next=s->right;if(s->longest_val<next->longest_val+1)          {              s->longest_val=next->longest_val+1;              s->dp1=next;          }  }if(s->left!=NULL){node *next=s->left;if(s->dp1!=next)              s->second_val=max(s->second_val,next->longest_val+1);  }if(s->right!=NULL){node *next=s->right;if(s->dp1!=next)s->second_val=max(s->second_val,next->longest_val+1);}}void dfs2(node *&s)      //第二次深搜{if(s->left!=NULL){node *next=s->left;if(s->dp1!=next)              next->dp=max(s->dp,s->longest_val)+1;                     else              next->dp=max(s->dp,s->second_val)+1;          dfs2(next);  }}void find(node *&s){if(s!=NULL){max1=max(max1,max(s->dp,s->longest_val));find(s->left);find(s->right);}}int main(){max1=-maxn;node *root=NULL;newset(root,10);newset(root,6);newset(root,14);newset(root,4);newset(root,8);newset(root,12);newset(root,16);newset(root,50);dfs1(root);dfs2(root);find(root);cout<<max1<<endl;return 0;}