题目:输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。
例如: 输入整数22和如下二元树
10
/ /
5 12
/ /
4 7
则打印出两条路径:10, 12和10, 5, 7。
此方法用了双向链表来保存路径,当然也可以用容器Vector来构造队列结构来保存路径。
#include <iostream>
using namespace std;
struct BinaryTreeNode // a node in the binary tree
{
int m_nValue; // value of node
BinaryTreeNode *m_pLeft; // left child of node
BinaryTreeNode *m_pRight; // right child of node
};
//打印路径
void printPath(BinaryTreeNode *path);
/**
*sum为要求的整数和
*curSum为从根节点到tree父节点,路径上所有数的和
*path指向当前路径的最后一个节点,该路径有BinaryTreeNode组成双向链表
*m_pRight指向路径下一节点,m_pLeft指向上一节点
**/
void searchPath(BinaryTreeNode *tree,BinaryTreeNode *path,int curSum,int sum)
{
curSum += tree->m_nValue;
//路径值已经大于所求和,返回
if(curSum>sum)
return;
BinaryTreeNode *node=new BinaryTreeNode();
node->m_nValue=tree->m_nValue;
//将当前节点的值加入到路径中
if(path==NULL)
path=node;
else
{
path->m_pRight=node;
node->m_pLeft=path;
path=node;
}
if(curSum==sum)
{
//路径结束且和=sum,为所求
if(tree->m_pLeft==NULL&&tree->m_pRight==NULL)
{
//获得路径头节点,用于打印
while(path->m_pLeft)
path=path->m_pLeft;
printPath(path);
}
//若当前路径的和=sum,但路径还未到达叶节点,此路径不可行
delete node;
return;
}
//curSum<sum,继续搜寻路径
if(tree->m_pLeft!=NULL)
searchPath(tree->m_pLeft,path,curSum,sum);
if(tree->m_pRight!=NULL)
searchPath(tree->m_pRight,path,curSum,sum);
delete node;
}
void printPath(BinaryTreeNode *path)
{
while(path)
{
cout<<path->m_nValue<<" ";
path=path->m_pRight;
}
cout<<endl;
}
void main()
{
BinaryTreeNode *root=NULL;
BinaryTreeNode node10;
node10.m_nValue=10;
BinaryTreeNode node5;
node5.m_nValue=5;
BinaryTreeNode node12;
node12.m_nValue=12;
BinaryTreeNode node4;
node4.m_nValue=4;
BinaryTreeNode node7;
node7.m_nValue=7;
node10.m_pLeft=&node5;
node10.m_pRight=&node12;
node5.m_pLeft=&node4;
node5.m_pRight=&node7;
node12.m_pLeft=node12.m_pRight=NULL;
node4.m_pLeft=node4.m_pRight=NULL;
node7.m_pLeft=node7.m_pRight=NULL;
root=&node10;
BinaryTreeNode *path=NULL;
cout<<"搜寻值为22的路径有如下几条:"<<endl;
searchPath(root,path,0,22);
cin.get();
}