打印给定总和的所有路径的函数(二叉树C ++)

时间:2017-03-14 02:54:46

标签: c++ algorithm tree sum binary-tree

“给定二叉树和整数k。编写要打印的函数 树中路径中节点总和为k的每个路径。假设路径可以从任何节点开始并在任何节点结束,即它们不必是根节点和叶节点;树上还有负数。“

我仍然坚持通过遍历树来实现这一目标的逻辑。任何帮助/提示将非常感谢!

1 个答案:

答案 0 :(得分:2)

  

遍历树以实现此目标的逻辑

使用“深度优先”或“广度优先”搜索来访问树中的每个节点。

在每个节点开始新的搜索。

因为这个树是递归数据结构,所以我会使用递归来执行搜索。

并结束递归: - 更新03/14

1)在叶节点。

未找到目标总和时,因为存在负值

当总和超过目标总和时,因为存在负值

注意:我认为这简化了“总结”。行动很多。它现在是一个DF搜索终止于叶子,在特定节点处输出简单。

否' decurse'需要采取行动,因为DF / BF访问将探索所有分支。

更新3/18

我的代码中的一些示例输出。

' on-side-side'树显示(从左到右)

               '-3' 
          '-2' 
               '-1' 
     '0' 
               '1' 
          '2' 
                    '3' 
               '4' 
'5' 
               '6' 
          '7' 
                    '8' 
               '9' 
     '10' 
               '11' 
          '12' 
                    '13' 
               '14' 
                    '42' 

示例' targetSum'调查结果:(第41页,共41页)

BTree_t::dfVisit(-2)  
  start level 3:    -2 
  start level 2:     0   -2 

BTree_t::dfVisit(-1)  
  start level 4:    -1 

BTree_t::dfVisit(0)  
  start level 2:     0 
  start level 1:     5    0   -2   -3 

BTree_t::dfVisit(1)  
  start level 4:     1

更新2017/03/22

网上有很多深度优先搜索代码的例子。在我的方法中,树的贡献只是在根处开始搜索(或解释它为什么不能)。

// depth-first-visit of all nodes in tree
void BTree_t::dfVisitSum(const int targetSum)
{
   std::cout << "\n\n  BTree_t::dfVisitSum(" << targetSum << ") ";

   if(m_root)
   {
      int reportCount = m_root->dfVisitSum(targetSum);
      if(0 == reportCount)
         std::cout << "none";
    }
    else
    {
      std::cerr << "\n  dfVisitSum() Note: tree has no elements.."
                << std::endl;
   }
}

如果我们现在查看节点dfVisitSum(),我们注意到它有一个有限的持续时间&#39; nodeLog&#39;传递到sumSearch():

// depth-first-visit of all nodes below the current node
int Node_t::dfVisitSum(const int targetSum)
{
   int reportCount = 0;

   // dfs search left, then do something, then search right
   if(m_left)  {  reportCount += m_left->dfVisitSum(targetSum); }

   {
      // while visiting this node, create a vector for logging 
      NVec_t  nodeLog;   
      nodeLog.reserve(nodeDepthMax()); 

      // start a new depth-first-search called "sumSearch()
      reportCount += sumSearch(targetSum, nodeLog);  

   }  // nodeLog terminates here

   if(m_right) { reportCount += m_right->dfVisitSum(targetSum); }

   return (reportCount);
}

最后,

// target-sum-search
int Node_t::sumSearch(const int targetSum, NVec_t& nodeLog)
{
   int reportCount = 0;

   // capture visit of this node to log
   nodeLog.push_back(this); 

   // in dfs style, first search down the left 
   if(m_left)  {  reportCount += m_left->sumSearch(targetSum, nodeLog); }

   { // now do something in this node
      size_t   startLvl = nodeLog[0]->m_lvl; // for report

      int accumulateSum = 0;
      for (size_t i = 0; i < nodeLog.size(); ++i)
         accumulateSum += nodeLog[i]->m_payLoad;
      // sure, sure, use std::accumulate with a lambda, if you wish

      if (targetSum == accumulateSum)
      {
         std::stringstream reportLabelSS; // convenience
         reportLabelSS << "\n     @ level " << startLvl << ":";
         std::cout << showNVec(nodeLog, reportLabelSS.str());
         // this output displays start level and nodes-visited payloads
         reportCount += 1;  // report occurrence north bound to caller
      }
   }
   // in dfs style, search down the right
   if(m_right) { reportCount += m_right->sumSearch(targetSum, nodeLog); }

   // discard / clear  this node visit from log, we are out-a-here
   nodeLog.pop_back(); // removes last nodeLog element
   return(reportCount); // report count
}