求二叉树中节点的最大距离...
如果我们把二叉树看成一个图,
父子节点之间的连线看成是双向的,
我们姑且定义"距离"为两节点之间边的个数。
写一个程序,
求一棵二叉树中相距最远的两个节点之间的距离。
---------------------------------
其实遇到这种二叉树问题,最先想到的办法应该是遍历,先序 后序 中序 总之这种遍历能够得到你想要的各种信息!!
看看这题,想要找节点距离最远的,当然是找出某个节点左右子树节点最深的距离差了,好了,既然要找节点左右子树的深度,那就必须递归找出各个节点的深度了,那么这题的思路就豁然开朗了,不过每次递归都必须记住 距离的记录!
//============================================================================
// Name : BTCalcMaxDistance.cpp
// Author : YLF
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <stdio.h>
#include <malloc.h>
using namespace std;
struct Node{
int value;
Node* left;
Node* right;
};
int maxD;
void addNode(Node* &p, int value);
void printBT(Node* p);
int maxDistance(Node* p);
int main() {
Node* head = NULL;
int input = 0;
int num = -1;
while(true){
num++;
cin>>input;
if(input != -1)
addNode(head, input);
else
break;
}
//
printBT(head);
if(maxDistance(head) != 0)
cout<<"maxDistance:"<<maxD;
return 0;
}
void addNode(Node* &p, int value){
if(p == NULL){
Node* temp = (Node*)malloc(sizeof(Node));
temp->value = value;
temp->left = NULL;
temp->right = NULL;
p = temp;
return;
}
if(value < p->value)
addNode(p->left, value);
else if(value >= p->value)
addNode(p->right, value);
}
/**
* 计算最大距离
* 思想是,最大距离就是某个节点的左右节点深度距离和
* 所以我们只要计算出每个节点的左右节点最深的距离即可
* 比较出我们需要的最大值
*/
int maxDistance(Node* p){
if(p == NULL)
return 0;
if(p->left == NULL && p->right == NULL){
return 0;
}
int ln = 0;
int rn = 0;
if(p->left != NULL)
ln = 1 + maxDistance(p->left);
if(p->right != NULL)
rn = 1 + maxDistance(p->right);
int diff = ln + rn;
maxD = maxD>diff?maxD:diff;
return (ln>rn)?ln:rn;
}
/**
* 打印测试
*/
void printBT(Node* p){
if(p == NULL)
return;
if(p->left != NULL)
printBT(p->left);
cout<<p->value<<" ";
if(p->right != NULL)
printBT(p->right);
}
我的思路是在每次递归返回的时候得出改节点的最大距离差以及该点的最深的子树值,然后更新
下面给出一个利用结构体存储距离方式
来自:http://bbs.csdn.net/topics/350118968
// 数据结构定义
struct NODE
{
NODE* pLeft; // 左子树
NODE* pRight; // 右子树
int nMaxLeft; // 左子树中的最长距离
int nMaxRight; // 右子树中的最长距离
char chValue; // 该节点的值
};
int nMaxLen = 0;
// 寻找树中最长的两段距离
void FindMaxLen(NODE* pRoot)
{
// 遍历到叶子节点,返回
if(pRoot == NULL)
{
return;
}
// 如果左子树为空,那么该节点的左边最长距离为0
if(pRoot -> pLeft == NULL)
{
pRoot -> nMaxLeft = 0;
}
// 如果右子树为空,那么该节点的右边最长距离为0
if(pRoot -> pRight == NULL)
{
pRoot -> nMaxRight = 0;
}
// 如果左子树不为空,递归寻找左子树最长距离
if(pRoot -> pLeft != NULL)
{
FindMaxLen(pRoot -> pLeft);
}
// 如果右子树不为空,递归寻找右子树最长距离
if(pRoot -> pRight != NULL)
{
FindMaxLen(pRoot -> pRight);
}
// 计算左子树最长节点距离
if(pRoot -> pLeft != NULL)
{
int nTempMax = 0;
if(pRoot -> pLeft -> nMaxLeft > pRoot -> pLeft -> nMaxRight)
{
nTempMax = pRoot -> pLeft -> nMaxLeft;
}
else
{
nTempMax = pRoot -> pLeft -> nMaxRight;
}
pRoot -> nMaxLeft = nTempMax + 1;
}
// 计算右子树最长节点距离
if(pRoot -> pRight != NULL)
{
int nTempMax = 0;
if(pRoot -> pRight -> nMaxLeft > pRoot -> pRight -> nMaxRight)
{
nTempMax = pRoot -> pRight -> nMaxLeft;
}
else
{
nTempMax = pRoot -> pRight -> nMaxRight;
}
pRoot -> nMaxRight = nTempMax + 1;
}
// 更新最长距离
if(pRoot -> nMaxLeft + pRoot -> nMaxRight > nMaxLen)
{
nMaxLen = pRoot -> nMaxLeft + pRoot -> nMaxRight;
}
}
//很明显,思路完全一样,但书上 给的这段代码 更规范!:)。