微软面试百题010——二叉树节点最大距离

1.问题描述:

求二叉树结点中的最大距离(假设二叉树中节点都可以是双向的)

2.思路:

先援引一段很牛逼的英文:
ANSWER:
This is interesting... Also recursively(递归的), the longest distance between two nodes must be either from root to one leaf, or between two leafs. For the former case, it’s the tree height. For the latter case, it should be the sum of the heights of left and right subtrees of the two leaves’ most least ancestor.
The first case is also the sum the heights of subtrees, just the height + 0.

根据上面的解答,我们会发现,二叉树中节点之间的最大的距离只有三种情况
第一种:经过根节点
第二种:全在左子树中
第三种:全在右子树中

所以说我们可以用递归的思路来求解这个问题:

3.代码:

#include"iostream"
#include"cstdio"
#include"cstdlib"
#include"cstring"
#define N 100

using namespace std;

typedef struct node
{
	struct node* left;
	struct node* right;
	int data;
}point;

class tree
{
	public:
		tree()
		{
			memset(preorder,0,sizeof(preorder));
			memset(midorder,0,sizeof(midorder));
			root=NULL;
			num=ans=0;
		}
		void set()
		{
			cout<<"节点数目"<<endl;
			cin>>num;
			cout<<"前序遍历"<<endl;
			for(int i=0;i<num;i++) cin>>preorder[i];
			cout<<"后序遍历"<<endl;
			for(int i=0;i<num;i++) cin>>midorder[i];
		}
		void prebuild()
		{
			root=buildtree(preorder,midorder,num);
		}
		point* buildtree(int* pre,int* mid,int i)   //i代表个数,构造函数类似于前序遍历的过程,只不过接住了中序遍历来进行划分 
		{
			if(i==0) return NULL;
			point* k=new point;
			k->data=pre[0];
			k->left=k->right=NULL;
			int* p;
			int* q;
			int w=0;
			for(int i=0;i<num;i++) 
			{
				if(mid[i]==pre[0])
				{
					w=i;
					break;
				}
			}
			p=pre+1;
			q=mid;
			k->left=buildtree(p,q,w);
			p=pre+w+1;
			q=mid+w+1;
			k->right=buildtree(p,q,i-w-1);   //w是左子树的个数,1是根节点的个数,i-w-1就是右子树的个数
			return k; 
		}
		void maxsituation(point* p,int& k)   //返回目前最大的状态
		{
			if(p==NULL) 
			{
				k=-1;
			}
			else
			{
				int l,r;
				maxsituation(p->left,l);
				l++;
				maxsituation(p->right,r);
				r++;
				ans=max(max(ans,l),max(r,l+r));    //更新结果 
				if(p==root) return ;
				k=max(l,r);   //利用引用,k代表当前节点伟根的子树可以贡献的最大的长度,这个长度的路径必定果根节点 
			}
		}
		void p()
		{
			maxsituation(root,ans);
			cout<<"结果是"<<ans<<endl;
		}
		point* returnroot()
		{
			return root;
		} 
		void previsit(point* p)
		{
			if(p==NULL) return ;
			else
			{
				cout<<p->data<<' ';
				previsit(p->left);
				previsit(p->right);
				return ;
			}
		}
	private:
		int preorder[N];
		int midorder[N];
		point* root;
		int num;
		int ans;
};

int main()
{
	tree my;
	my.set();
	my.prebuild();
	my.previsit(my.returnroot());
	my.p();
	return 0;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值