题目:
把二叉树看成一个图,父子节点之间的连线看成是双向的,定义“距离”为两个节点之间的边数。
求一颗二叉树中的两个节点之间的距离的最大值。
方法一:用书上写的方法:
代码:
struct node { node *left; node *right; int nMaxLeft; int nMaxRight; char ch; }; int nMaxLength = 0; void FindMaxDistance(node *root) { if(root == NULL) return ; if(root->left == NULL) root->nMaxLeft = 0; if(root->right == NULL) root->nMaxRight = 0; if(root->left != NULL) FindMaxDistance(root->left); if(root->right != NULL) FindMaxDistance(root->right); if(root->left != NULL) { int temp = 0; if(root->left->nMaxLeft > root->left->nMaxRight) temp = root->left->nMaxLeft; else temp = root->left->nMaxRight; root->nMaxLeft = temp + 1; } if(root->right != NULL) { int temp = 0; if(root->right->nMaxLeft > root->right->nMaxRight) temp = root->right->nMaxLeft; else temp = root->right->nMaxRight; root->nMaxRight = temp + 1; } if(root->nMaxLeft + root->nMaxRight > nMaxLength) nMaxLength = root->nMaxLeft + root->nMaxRight; }
方法二:
定义:经过节点x作为根节点的子树中,节点间的最大距离为Dis(x)。
在求过点x的最大距离时,最大距离的两个点有可能出现在三种情况下
- 左子树
- 右子树
- 过节点x
经分析得出以下特点
- 以上三种情况最终必定一叶子结束
- 在第三种情况下必然是左子树高度 与 右子树高度 之和(只有这样,才可能取得最大值)
经过以上分析即可得出递推式
Dis(x) = max(Dis(x->left), Dis(x->right), height(x->left)+height(x->right))
代码:
struct node { node *left; node *right; char ch; }; int maxLength = 0; int Height(node *root) { if(root == NULL) return 0; return Height(root->left) > Height(root->right) ? Height(root->left)+1 : Height(root->right)+1; } int FindMaxDistance(node *root) { if(root == NULL) return 0; else if(root->left == NULL && root->right == NULL) return 0; int dis = max(FindMaxDistance(root->left), FindMaxDistance(root->right), Height(root->left)+Height(root->right)); if (dis > maxLength) maxLength = dis; return dis; }
方法三:
思路:利用深度优先遍历的方法。
这两点必然在以某个节点 A 为根的子树上,它们间的路径必然经过该子树的根节点 A 。
因而,以任意一个节点为根的子树,计算出经过该子树根节点的最大距离,则所有最大距离的最大值就是所要求的最大距离。
而经过一个树的根节点的最大距离 = 左子树的高度 + 右子树的高度 +2 (假设空节点的高度为 -1 ),因而可以用一个全局变量 max_d 保存最大距离,采用深度优先遍历,每遍历一个节点,计算出左右子树的高度,计算出其高度,并将经过该节点的最大距离值与 max_d 值比较,并更新 max_d ,
当遍历完所有节点时, max_d 就是所求的最大距离。
代码:
int maxLen = 0; int FindMaxDistance(node *root, int &maxLen) { //每碰到一个子节点,高度自增1,可以设空节点高度为-1, //避免计算高度时对空节点的判断。 if(root == NULL) return -1; int leftLen = FindMaxDistance(root->left, maxLen) + 1; int rightLen = FindMaxDistance(root->right, maxLen) + 1; if(leftLen + rightLen > maxLen) maxLen = leftLen + rightLen; return leftLen > rightLen ? leftLen : rightLen; }
时间: 2024-10-26 08:07:19