二叉樹中和爲某一值的路徑

題目:輸入一個二叉樹和一個整數,打印出二叉樹中結點值的和爲輸入整數的所有路徑。

 

分析:

從樹的根結點開始一直往下直到葉結點所經過的結點形成一條路徑,因此要採用前序遍歷。遍歷過程中要把訪問過的結點保存下來,這樣當某一條路徑滿足要求時才能打印該路徑。

由於是前序遍歷,所以每次在遍歷下一個結點之前,先要從當前結點回到其父結點,然後再遍歷父結點的右子結點。當然,由於要遍歷右子結點,當前的左子結點已經不在該路徑上了,故要在遍歷之前先把左子結點從原路徑中刪除。

如果當前結點是葉結點,並且當前的和等於輸入的整數,則打印該路徑。如果不是葉結點,則繼續訪問其子結點。當前結點訪問之後,退出函數之前,要在路徑上刪除當前結點並減去當前結點的值,以確保返回父結點時的路徑是從根結點到父結點的路徑。

採用遞歸的方式實現,下面是參考代碼:

 

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();
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章