“给定二叉树和整数k。编写要打印的函数 树中路径中节点总和为k的每个路径。假设路径可以从任何节点开始并在任何节点结束,即它们不必是根节点和叶节点;树上还有负数。“
我仍然坚持通过遍历树来实现这一目标的逻辑。任何帮助/提示将非常感谢!
答案 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
}