//题意:
//输出二叉树的路径和为给定数值的所有路径;
//二叉树路径是从根节点向下一直到叶子节点的所有节点形成的路径。
//思路:
// 1. 采用前序遍历方式访问某一个节点时,我们把节点加到路径上并累加节点值
// 1) 如果该节点为叶子节点并且路劲中累加和恰好为输入的整数值时输出当前路径;
// 2) 如果该节点不是叶子节点,则继续寻找该节点的左孩子或右节点;
// 2. 如果该路径节点已经是叶子节点后则返回父节点,并且当前路径上减去该节点值,保证返回父节点时路径正确。
#include <iostream>
#include <vector>
using namespace std;
int preOrder[] = {1, 2, 4, 5, 7};
int inOrder[] = {4, 2, 5, 1, 7};
typedef struct Node_
{
int data;
Node_ * left, * right;
}Node;
vector<int> path;
//前序遍历树
void preOrderTree(Node *root)
{
if(!root)
{
return;
}
printf("%d ", root->data);
preOrderTree(root->left);
preOrderTree(root->right);
}
//利用前序数组和后续数组重建
Node * Rebuild(Node * &root, int preOrder[], int inOrder[], int n, int pl, int pr, int il, int ir)
{
int i = 0;
for (i = il; i <= ir; ++i)
{
if (inOrder[i] == preOrder[pl])
{
break;
}
}
int k = i - il;
if (i > ir)
{
root = 0;
return root;
}
else
{
root = new Node();
root->data = inOrder[i];
}
root->left = Rebuild(root->left, preOrder, inOrder, n, pl + 1, pl + k, il, i - 1);
root->right = Rebuild(root->right, preOrder, inOrder, n, pl + k + 1, pr, i + 1, ir);
return root;
}
//遍历树的路径,输出节点值
void SumTree(Node *root, int & curSum, int sum)
{
if (!root)
{
return;
}
curSum += root->data;
path.push_back(root->data);
bool isLeaf = (!root->left && !root->right);
if (curSum == sum && isLeaf)
{
vector<int>::iterator iter = path.begin();
while(iter != path.end())
{
printf("%d ", *iter);
iter++;
}
printf("\n");
}
SumTree(root->left, curSum, sum);
SumTree(root->right, curSum, sum);
curSum -= root->data;
path.pop_back();
}
int main()
{
int n = sizeof(preOrder) / sizeof(preOrder[0]);
Node * root = Rebuild(root, preOrder, inOrder, n, 0, n-1, 0, n-1);
printf("Pre Order:");
preOrderTree(root);
printf("\n");
printf("Path:\n");
int curSum = 0;
int sum = 8;
path.clear();
SumTree(root, curSum, sum);
return 0;
}