題目:輸入一個二叉樹和一個整數,打印出二叉樹中結點值的和爲輸入整數的所有路徑。
分析:
從樹的根結點開始一直往下直到葉結點所經過的結點形成一條路徑,因此要採用前序遍歷。遍歷過程中要把訪問過的結點保存下來,這樣當某一條路徑滿足要求時才能打印該路徑。
由於是前序遍歷,所以每次在遍歷下一個結點之前,先要從當前結點回到其父結點,然後再遍歷父結點的右子結點。當然,由於要遍歷右子結點,當前的左子結點已經不在該路徑上了,故要在遍歷之前先把左子結點從原路徑中刪除。
如果當前結點是葉結點,並且當前的和等於輸入的整數,則打印該路徑。如果不是葉結點,則繼續訪問其子結點。當前結點訪問之後,退出函數之前,要在路徑上刪除當前結點並減去當前結點的值,以確保返回父結點時的路徑是從根結點到父結點的路徑。
採用遞歸的方式實現,下面是參考代碼:
TreeNode.h
struct BinaryTreeNode
{
int m_value;
BinaryTreeNode *pleft;
BinaryTreeNode *pright;
};
#include <iostream>
#include <vector>
#include "TreeNode.h"
using namespace std;
BinaryTreeNode *creat_binarytree(unsigned int n);
void FindPath(BinaryTreeNode *proot,int expectedsum);
void FindPath(BinaryTreeNode *proot,int expectedsum,vector<int> &path,int currentsum);
int main()
{
BinaryTreeNode *proot=creat_binarytree(5);
FindPath(proot,22);
return 0;
}
BinaryTreeNode *creat_binarytree(unsigned int n)
{
BinaryTreeNode *proot=NULL;
BinaryTreeNode *node[20];
int i=0,j=0;
int e;
while(i < n)
{
cin>>e;
BinaryTreeNode *p=new BinaryTreeNode();
p->m_value=e;
p->pleft=NULL;
p->pright=NULL;
node[i]=p;
if (i == 0)
{
proot=p;
}
else
{
j = (i+1)/2;
if(i & 1 == 1)
{
node[j-1]->pleft=p;
}
else
{
node[j-1]->pright=p;
}
}
i++;
}
return proot;
}
void FindPath(BinaryTreeNode *proot,int expectedsum)
{
if (proot==NULL)
{
return;
}
vector<int> path;
int currentsum=0;
FindPath(proot,expectedsum,path,currentsum);
}
void FindPath(BinaryTreeNode *proot,int expectedsum,vector<int> &path,int currentsum)
{
currentsum += proot->m_value;
path.push_back(proot->m_value);
//是否爲葉結點。如果是葉結點,並且路徑上結點的和等於輸入的值,打印該路徑
bool isleaf = proot->pleft==NULL && proot->pright==NULL;
if (currentsum==expectedsum && isleaf)
{
cout <<"A path is found: \n";
vector<int>::iterator iter=path.begin();
for (;iter != path.end();iter++)
{
cout <<*iter <<"\t" ;
}
cout <<endl;
}
//如果不是葉結點,遍歷它的子結點
if (proot->pleft!=NULL)
{
FindPath(proot->pleft,expectedsum,path,currentsum);
}
if (proot->pright!=NULL)
{
FindPath(proot->pright,expectedsum,path,currentsum);
}
//返回父結點之前,在路徑上刪除當前結點
path.pop_back();
}