/******************************************************************
题目:输入一颗二叉树和一个整数,打印出二叉树中节点值的和为输入整数
的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路
径。
******************************************************************/
#include<stdio.h>
#include<vector>
using namespace std;
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
BinaryTreeNode* createBinaryTreeNode(int value)
{
BinaryTreeNode* pNode = new BinaryTreeNode();
pNode->m_nValue = value;
pNode->m_pLeft = NULL;
pNode->m_pRight = NULL;
return pNode;
}
void connectBinaryTreeNode(BinaryTreeNode* pParent, BinaryTreeNode* pLeftChild,
BinaryTreeNode* pRightChild)
{
if(!pParent)
return;
pParent->m_pLeft = pLeftChild;
pParent->m_pRight = pRightChild;
}
void findPath(BinaryTreeNode* pRoot, int expectedSum,
vector<int>& path, int& currentSum);
void printPathInTree(BinaryTreeNode* pRoot, int expectedSum)
{
if(!pRoot)
return;
vector<int> path;
int currentSum = 0;
//为了使currentSum和path不重复被递归定义,所以重新调用一个新函数。
findPath(pRoot,expectedSum,path,currentSum);
}
//可以想到必须记录遍历过点的和,且有可能需要打印遍历过的点,所以有引用型参数。
void findPath(BinaryTreeNode* pRoot, int expectedSum,
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 found:");
vector<int>::iterator iter = path.begin();
for(; iter!=path.end(); ++iter)
printf("%d\t",*iter);
printf("\n");
}
if(pRoot->m_pLeft)
findPath(pRoot->m_pLeft,expectedSum,path,currentSum);
if(pRoot->m_pRight)
findPath(pRoot->m_pRight,expectedSum,path,currentSum);
currentSum -= pRoot->m_nValue;
path.pop_back();
}
void test()
{
BinaryTreeNode* pNode1 = createBinaryTreeNode(10);
BinaryTreeNode* pNode2 = createBinaryTreeNode(5);
BinaryTreeNode* pNode3 = createBinaryTreeNode(12);
BinaryTreeNode* pNode4 = createBinaryTreeNode(4);
BinaryTreeNode* pNode5 = createBinaryTreeNode(7);
connectBinaryTreeNode(pNode1,pNode2,pNode3);
connectBinaryTreeNode(pNode2,pNode4,pNode5);
printPathInTree(pNode1,22);
}
int main()
{
test();
return 0;
}
用vector方便变量已存节点
void FindPath(BinaryTreeNode* pRoot, int value)
{
if(pRoot == NULL)
return;
std::vector<BinaryTreeNode*> btnVector;
int sum = 0;
printBinaryTreeEquealValue(pRoot, value, btnVector, sum);
}
void printBinaryTreeEquealValue(BinaryTreeNode* pRoot, int value, vector<BinaryTreeNode*>& btnVector, int& sum)
{
BinaryTreeNode* pNode = pRoot;
if(!pNode->m_pLeft && !pNode->m_pRight)
{
if(sum == value)
{
vector<BinaryTreeNode*>::iterator iter = btnVector.begin();
for(;iter < btnVector.end(); ++iter)
{
cout << (*iter)->m_nValue << " ";
}
}
BinaryTreeNode* pTemp = btnVector.back();
btnVector.pop_back();
sum -= pTemp->m_nValue;
}
else
{
btnVector.push_back(pNode);
sum += pNode->m_nValue;
if(pNode->m_pLeft)
{
printBinaryTreeEquealValue(pRoot, value, btnVector, sum);
}
if(pNode->m_pRight)
{
printBinaryTreeEquealValue(pRoot, value, btnVector, sum);
}
}
}