如果把二叉树看成一个图,父子节点之间的连线看成是双向的,则定义距离为:两个节点之间边的个数
求一棵二叉树中相距最远的两个节点之间的距离
相距最远的两个节点一定是叶子节点,可以分为两种情况:
1.若最远距离的路径经过根ROOT,则两个最远的节点分别为两个不同子树的叶子结点,如图1

图1
2.若路径不经过ROOT,那么这两个节点一定属于根的K个子树之一,并且它们也是该子树中相距最远的两个顶点,如图2

图2
总结:最大距离为某个结点左子树的高度加上右子树高度
/********************************************************************************/
/* 计算二叉树中节点的最大距离,即求一棵二叉树中相距最远的两个节点之间的距离 */
/********************************************************************************/
#include<iostream>
#include<malloc.h>
#include<stdlib.h>
#define ERROR 0
using namespace std;
struct BiTree//标识一棵树
{
BiTree *lchild;
BiTree *rchild;
int m_nValue;
};
void InitTree(BiTree *&root)//初始化一棵二叉树(默认为满二叉树)
{
int data;
cin>>data;
root=(BiTree*)malloc(sizeof(BiTree));//生成根结点
if(!root)exit(ERROR);
root->m_nValue=data;
if(root->m_nValue==0)//如果根结点值为0,则释放掉
{
root=NULL;
free(root);
}
else if(root!=NULL)
{
InitTree(root->lchild);
InitTree(root->rchild);
}
}
//通过先序遍历和中序列遍历确定树的形状
void PreTraverse(BiTree *root)//先序
{
if(root)
cout<<root->m_nValue<<" ";
if(root->lchild)
PreTraverse(root->lchild);
if(root->rchild)
PreTraverse(root->rchild);
}
void MidTraverse(BiTree *root)//中序
{
if(root->lchild)
MidTraverse(root->lchild);
if(root)
cout<<root->m_nValue<<" ";
if(root->rchild)
MidTraverse(root->rchild);
}
int Max(int a,int b)
{
if(a>b)
return a;
else
return b;
}
int GetHeight(BiTree *root)//获得树的高度
{
int len;
if(root==NULL)
return 0;
else
return Max(GetHeight(root->lchild),GetHeight(root->rchild))+1;
}
int SearchMaxLen(BiTree *root)//获得结点距离最大的结点,最大距离为某个结点左子树的高度加上右子树高度
{
static int MaxLen=0;
int temp;
if(root)
{
temp=GetHeight(root->lchild)+GetHeight(root->rchild);//左子树的高度加右子树的高度
if(temp>MaxLen)
MaxLen=temp;
}
if(root->lchild)
SearchMaxLen(root->lchild);//递归查找左子树
if(root->rchild)
SearchMaxLen(root->rchild);//递归查找右子树
return MaxLen;
}
int main()
{
int data;
int MaxDistance;
BiTree *root=NULL;
InitTree(root);
cout<<"先序遍历:";
PreTraverse(root);
cout<<endl;
cout<<"中序遍历:";
MidTraverse(root);
cout<<endl;
cout<<"最大距离:"
MaxDistance=SearchMaxLen(root);
cout<<MaxDistance;
return 1;
}