关闭

编程之美读书笔记-求二叉树中节点的最大距离

193人阅读 评论(0) 收藏 举报
分类:

题目:如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义距离为两个节点之间边的个数。写一个程序求一棵二叉树中相距最远的两个节点之间的距离。如图所示,粗箭头的边表示最长距离。


解析:计算一个二叉树的最大距离有两个情况。
情况A:路径经过左子树的最深节点,通过根节点,再到右子树的最深节点。
情况B:路径不穿过根节点,而是左子树或右子树的最大距离路径,取其大者。


只需要计算这两个情况的路径距离,并取其大者,就是该二叉树的最大距离。

#include<iostream>  
using namespace std; 

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;
	}

}

void Link(NODE* nodes, int parent, int left, int right)
{
	if (left != -1)
		nodes[parent].pLeft = &nodes[left];
	if (right != -1)
		nodes[parent].pRight = &nodes[right];
}

int main() 
{
	NODE nodes[10] = { 0 };
	Link(nodes, 1, -1, 2);
	Link(nodes, 2, 3, 4);
	Link(nodes, 3, 5, -1);
	Link(nodes, 4, 6, 7);
	Link(nodes, 5, 8, -1);
	Link(nodes, 6, -1, 9);
	NODE* pRoot = NULL;
	FindMaxLen(&nodes[1]);
	cout << nMaxLen << endl;
	return 0;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:169342次
    • 积分:2448
    • 等级:
    • 排名:第15204名
    • 原创:85篇
    • 转载:111篇
    • 译文:20篇
    • 评论:29条
    博客专栏
    最新评论