来自何海涛100题。
题目:输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。
例如输入整数22和如下二元树
10
/ \
5 12
/ \
4 7
则打印出两条路径:10, 12和10, 5, 7。
下面是我自己的分析。
这个题目其实可以简化成输出所有从根节点到叶子节点点的路径的问题,只不过是多了一个和为定值的条件。也是简单的递归,但是在递归的过程中有值的累加的传递,类似于以前的创建树的过程。其实看起来用静态变量比较整洁,在以前的二叉树的总结中创建二叉树就是用的局部静态变量,这里用了下引用传递,其实也不复杂。但是要注意,函数传参的时候不能在传常量了。代码如下:
#include <iostream>
#include <vector>
using namespace std;
typedef struct BTreeNode
{
struct BTreeNode *left;
struct BTreeNode *right;
int value;
}BTreeNode, *BTree;
const int INVALIED = -1;
void findPath(BTree rt, int exceptedSum, int ¤tSum, vector<int> &path);
void createTree(BTree &rt, int *treeValues, int &i);
void preOrderRe(BTree rt);
int main()
{
int treeValues[] = {10, 5, 4, -1, -1, 7, -1, -1, 12, -1, -1};
BTree rt = NULL;
int i = 0;
createTree(rt, treeValues, i);
vector<int> path;
int currentSum = 0;
findPath(rt, 22, currentSum, path);
return 0;
}
void createTree(BTree &rt, int *treeValues, int &i)
{
if(treeValues == NULL)
return;
int value = treeValues[i];
if(value == INVALIED)
{
rt = NULL;
return;
}
rt = (BTree)malloc(sizeof(BTreeNode));
rt->value = value;
createTree(rt->left, treeValues, ++i);
createTree(rt->right, treeValues, ++i);
}
void findPath(BTree rt, int exceptedSum, int ¤tSum, vector<int> &path)
{
if(rt == NULL)
return;
currentSum += rt->value;
path.push_back(rt->value);
//如果改成if(rt->left == NULL && rt->right == NULL) 就是输出所有从根到叶子节点的路径了
if(rt->left == NULL && rt->right == NULL && currentSum == exceptedSum)
{
for(vector<int>::iterator it = path.begin(); it != path.end(); ++it)
printf("%d\n", *it);
printf("\n");
return;
}
if(rt->left != NULL)
{
findPath(rt->left, exceptedSum, currentSum, path);
currentSum -= rt->left->value;
path.pop_back();
}
if(rt->right != NULL)
{
findPath(rt->right, exceptedSum, currentSum, path);
currentSum -= rt->right->value;
path.pop_back();
}
}