目录
1.题目概述:
假设二叉树中的所有节点值为int类型,采用二叉链表存储。设计递归算法求二叉树bt中从根结点到叶子结点路径和最大的一条路径。例如,对于下图所示的二叉树,路径和最大的一条路径是5→4→6,路径和是15.
2.题目解析:
路径:被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。
路径和:是路径中各节点值的总和。
题目思路:递归实现。
递归函数的定义:求解包含根节点的最大路径和。递归终止条件:
如果根节点为null,直接返回0。
递归过程:
递归求解包含左孩子的以左孩子为根结点的最大路径和maxLeft,以及包含右孩子的以左孩子为根结点的最大路径和maxRight。
如果maxLeft > 0,我们的当前的最大路径和就应该加上maxLeft。
如果maxRight > 0,我们的当前的最大路径和就应该加上maxRight。
最大路径和maxResult取maxResult和当前最大路径和的较大值。
该递归函数的返回结果应该是根节点的值,根节点的值加上maxLeft的值,根节点的值加上maxRight的值,这三者间的较大值。
时间复杂度和空间复杂度均为O(h),其中h为树的高度。
3.题目代码:
#include <stdio.h>
#include <stdlib.h>
#define exitence -1
typedef struct BiTNode
{
int data;
struct BiTNode *lTree, *rTree;
} BiTNode, *BiTree;
void CreateBiTree(BiTree *T)
{
int n;
scanf("%d", &n);
if (n == 0)
*T = NULL;
else
{
*T = (BiTNode *)malloc(sizeof(BiTNode));
if (NULL == *T)
exit(exitence);
(*T)->data = n;
CreateBiTree(&((*T)->lTree));
CreateBiTree(&((*T)->rTree));
}
}
int RouteSumMax();
void Route();
int Max();
int main()
{
BiTree T = NULL;
printf("请输入所有节点的数值:\n");
CreateBiTree(&T);
printf("路径和最大的一条路径是:");
Route(T);
printf("\n路径和是:%d", RouteSumMax(T));
return 0;
}
int Max(int x, int y)
{
if (x >= y)
return x;
else
return y;
}
int RouteSumMax(BiTree T)
{
if (T == 0)
return 0;
else
return Max(T->data + RouteSumMax(T->lTree), T->data + RouteSumMax(T->rTree));
}
void Route(BiTree T)
{
if (T)
{
printf("%d ", T->data);
if (RouteSumMax(T->lTree) >= RouteSumMax(T->rTree))
{
Route(T->lTree);
}
else
{
Route(T->rTree);
}
}
}
4.样例展示:
5. 题目总结:
这个问题重难点在于首先是二叉树的构造,接着最重要的是采取递归函数计算左右子树的最大路径和。递归并非指整个函数递归,而是说其中一个子函数使用了递归,简单的理解为:当前节点的值,加上左子树递归结果和右子树递归结果的最大值,我认为,左子树和右子树的递归蕴含着分治策略的思想。这是对该问题的简要分析。