1.题目描述:
输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。二叉树结点的定义如下:
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
}
2.分析:
1)当用前序遍历的方式访问到某一结点时,我们把该结点添加到路径上,并累加该结点的值。如果该结点为叶结点并且路径中结点值的和刚好等于输入的整数,则当前的路径符合要求,我们把它打印出来。如果当前结点不是叶结点,则继续访问它的子结点。当前结点访问结束后,递归函数将自动回到它的父结点。因此我们在函数退出之前要在路径上删除当前结点并减去当前结点的值,以确保返回父结点时路径刚好是从根结点到父结点的路径。
2)我们不难看出保存路径的数据结构实际上是一个栈,因为路径要与递归调用状态一致,而递归调用的本质就是一个压栈和出栈的过程。
3.源代码:
#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
typedef struct BinaryTreeNode{
int m_nValue;
struct BinaryTreeNode* m_pLeft;
struct BinaryTreeNode* m_pRight;
}*BinaryTree;
void CreateTree(BinaryTree &T)
{
char buffer[10];
memset(buffer,0,10);
std::cin.getline(buffer,9);
int a = atoi(buffer);
if(a == 0) T = NULL;
else
{
T = (BinaryTree)malloc(sizeof(BinaryTreeNode));
T->m_nValue = a;
CreateTree(T->m_pLeft);
CreateTree(T->m_pRight);
}
}
void Print(BinaryTree T)
{
if(T)
{
cout<<T->m_nValue<<endl;
Print(T->m_pLeft);
Print(T->m_pRight);
}
}
void FindPath(BinaryTreeNode* pRoot,int expectedSum,std::vector<int>& path,int currentSum){
currentSum += pRoot->m_nValue;
path.push_back(pRoot->m_nValue);
//如果是叶结点,并且路径上结点的和等于输入的值,则打印出这条路径
bool isLeaf = pRoot->m_pLeft == NULL && pRoot->m_pRight == NULL;
if(currentSum == expectedSum && isLeaf)
{
printf("A path is founded:");
std::vector<int>::iterator iter = path.begin();
for(; iter!=path.end();++iter)
printf("%d\t",*iter);
printf("\n");
}
//如果不是叶结点,则遍历它的子结点
if(pRoot->m_pLeft != NULL)
FindPath(pRoot->m_pLeft,expectedSum,path,currentSum);
if(pRoot->m_pRight != NULL)
FindPath(pRoot->m_pRight,expectedSum,path,currentSum);
//在返回到父结点之前,在路径上删除当前结点。
path.pop_back();
}
void FindPath(BinaryTreeNode* pRoot,int expectedSum)
{
if(pRoot == NULL)
return;
std::vector<int> path;
int currentSum = 0;
FindPath(pRoot,expectedSum,path,currentSum);
}
int main(int argc,char *argv[])
{
BinaryTree T1;
cout<<"以先序遍历的顺序创建的二叉树T1:"<<endl;
CreateTree(T1);
cout<<"原始的二叉树T1的先序遍历序列为:"<<endl;
Print(T1);
int expectedSum;
cout<<"请输入期望值:";
cin>>expectedSum;
FindPath(T1, expectedSum);
cout<<endl;
return 0;
}
4.运行效果:
以先序遍历的顺序创建的二叉树T1:
10
5
4
#
#
7
#
#
12
#
#
原始的二叉树T1的先序遍历序列为:
10
5
4
7
12
请输入期望值:22
A path is founded:10 5 7
A path is founded:10 12
Program ended with exit code: 0