在只有节点值的二叉树中查找节点的祖先
Finding the ancestors of a node in a binary tree with only the value of a node
我正在尝试完成一个接受值的方法,我必须递归地在二叉树中找到具有匹配值的节点的祖先,到目前为止我 运行递归部分有点麻烦,这是 class 我正在使用的:
#ifndef TREETYPE_H
#define TREETYPE_H
#include <string>
#include <fstream>
#include "QueType.h"
using namespace std;
enum OrderType {PRE_ORDER, IN_ORDER, POST_ORDER};
template<class ItemType>
struct TreeNode;
template <class ItemType>
class TreeType
{
public:
TreeType(); // constructor
~TreeType(); // destructor
TreeType(const TreeType<ItemType>& originalTree);
void operator=(const TreeType<ItemType>& originalTree);
// copy constructor
void MakeEmpty();
bool IsEmpty() const;
bool IsFull() const;
int GetLength() const;
ItemType GetItem(ItemType item, bool& found);
void PutItem(ItemType item);
void DeleteItem(ItemType item);
void ResetTree(OrderType order);
ItemType GetNextItem(OrderType order, bool& finished);
void Print(ofstream& outFile) const;
string Ancestors(ItemType item) const;
string AncestorsNext(TreeNode<ItemType>* node, ItemType item) const;
private:
TreeNode<ItemType>* root;
QueType<ItemType> preQue;
QueType<ItemType> inQue;
QueType<ItemType> postQue;
};
template <class ItemType>
struct TreeNode
{
ItemType info;
TreeNode* left;
TreeNode* right;
};
这是我迄今为止使用祖先方法得到的结果:
// This recursive function will return the ancestors of item in reverse order.
template <class ItemType>
string TreeType<ItemType>::Ancestors(ItemType item) const{
string out="";
TreeNode<ItemType>* temp=root;
if(root==nullptr || root->info==item){
return "Value has no ancestors";
}
else{
if(temp->info>item){
out+=temp->info;
temp=temp->left;
TreeType<ItemType>::Ancestors(temp->info);
}
if(temp->info<item){
out+=temp->info;
temp=temp->right;
TreeType<ItemType>::Ancestors(temp->info);
}
}
return out;
}
我坚持如何使用递归来检查树中的下一个值和我的 temp
变量,如果它每次都设置为根。如果有其他方法我洗耳恭听!
不用递归,你可以简单地初始化 temp=root,然后使用 while 循环:
while ( temp->left && temp->right && temp->info != item )
{
if ( temp->info > item )
{
// your ancestor stuff
temp = temp->left;
}
else if ( temp->info < item )
{
// your ancestor stuff
temp = temp->right;
}
}
If there's another way im all ears!
考虑:
a) 将 "vector of TreeNodes" 作为第二个参数传递给 Ancestors() 方法。
b) 在递归搜索期间(我首先使用深度),在向量中使用 push_back 以在搜索期间捕获访问的祖先(节点*),
c) 并且当找到值时,return 感兴趣的祖先。
d) 如果未找到(在当前分支中),请在 'de-cursion' 期间使用 pop_back 删除不需要的祖先节点。
我使用该技术找到了总和为目标的节点。
示例输出:(搜索总和为 -5 的节点)
BTree_t::dfVisitSum(-5)
@ level 3: -2 -3
@ level 2: 0 -2 -3
在树中:(即测试输入)
BTree_t::showTallView(): (balance: 0 sz: 19)
-3
-2
-1
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
42
// target-sum-search
int Node_t::sumSearch(const int targetSum, NVec_t& nodeLog)
{
int reportCount = 0;
// diag only std::cout << " Node_t::sumSearch() " << m_payLoad << std::endl;
// CAPTURE visit to log
nodeLog.push_back(this); // trace node route (depth-first-search style)
if(m_left)
{
reportCount += m_left->sumSearch(targetSum, nodeLog); // RECURSE
}
{
size_t startLvl = nodeLog[0]->m_lvl; // used in report
int accumulateSum = 0;
for (size_t i = 0; i < nodeLog.size(); ++i)
accumulateSum += nodeLog[i]->m_payLoad;
if (targetSum == accumulateSum)
{
std::stringstream reportLabelSS;
reportLabelSS << "\n @ level " << startLvl << ":";
std::cout << showNVec(nodeLog, reportLabelSS.str());
reportCount += 1;
}
}
if(m_right)
{
reportCount += m_right->sumSearch(targetSum, nodeLog); // RECURSE
}
// REMOVE this node visit from log
nodeLog.pop_back(); // removes last nodeLog element // DE-CURSE
return(reportCount); // report count
}
我一直在思考如何使用递归来检查树中的下一个值,如果它每次都被设置为根的话。
这是一个简单的解决方案的常见错误。 (但如果您不能添加方法,则可能不会)
本质上,您试图在一个函数中做太多事情。
简单的解决方案是将当前函数拆分为 2 个函数,
a) 处理从哪里开始搜索的初始化,它不是递归的,
b) 和另一个执行递归的。
我希望以下内容能为您提供足够的提示(因为我没有使用模板)
template <class ItemType>
string TreeType<ItemType>::Ancestors(ItemType item) const
{
string out = AncestorsR(item, root) // invoke recursive funct
return out;
}
template <class ItemType>
string TreeType<ItemType>::AncestorsR(ItemType item,
TreeNode<ItemType>* temp) const
{
string out="";
if(temp==nullptr || temp->info==item)
{
return "Value has no ancestors";
}
else
{
if(temp->info>item)
{
out+=temp->info;
temp=temp->left;
TreeType<ItemType>::Ancestors(temp->info);
}
if(temp->info<item)
{
out+=temp->info;
temp=temp->right;
TreeType<ItemType>::Ancestors(temp->info);
}
}
return out;
}
我正在尝试完成一个接受值的方法,我必须递归地在二叉树中找到具有匹配值的节点的祖先,到目前为止我 运行递归部分有点麻烦,这是 class 我正在使用的:
#ifndef TREETYPE_H
#define TREETYPE_H
#include <string>
#include <fstream>
#include "QueType.h"
using namespace std;
enum OrderType {PRE_ORDER, IN_ORDER, POST_ORDER};
template<class ItemType>
struct TreeNode;
template <class ItemType>
class TreeType
{
public:
TreeType(); // constructor
~TreeType(); // destructor
TreeType(const TreeType<ItemType>& originalTree);
void operator=(const TreeType<ItemType>& originalTree);
// copy constructor
void MakeEmpty();
bool IsEmpty() const;
bool IsFull() const;
int GetLength() const;
ItemType GetItem(ItemType item, bool& found);
void PutItem(ItemType item);
void DeleteItem(ItemType item);
void ResetTree(OrderType order);
ItemType GetNextItem(OrderType order, bool& finished);
void Print(ofstream& outFile) const;
string Ancestors(ItemType item) const;
string AncestorsNext(TreeNode<ItemType>* node, ItemType item) const;
private:
TreeNode<ItemType>* root;
QueType<ItemType> preQue;
QueType<ItemType> inQue;
QueType<ItemType> postQue;
};
template <class ItemType>
struct TreeNode
{
ItemType info;
TreeNode* left;
TreeNode* right;
};
这是我迄今为止使用祖先方法得到的结果:
// This recursive function will return the ancestors of item in reverse order.
template <class ItemType>
string TreeType<ItemType>::Ancestors(ItemType item) const{
string out="";
TreeNode<ItemType>* temp=root;
if(root==nullptr || root->info==item){
return "Value has no ancestors";
}
else{
if(temp->info>item){
out+=temp->info;
temp=temp->left;
TreeType<ItemType>::Ancestors(temp->info);
}
if(temp->info<item){
out+=temp->info;
temp=temp->right;
TreeType<ItemType>::Ancestors(temp->info);
}
}
return out;
}
我坚持如何使用递归来检查树中的下一个值和我的 temp
变量,如果它每次都设置为根。如果有其他方法我洗耳恭听!
不用递归,你可以简单地初始化 temp=root,然后使用 while 循环:
while ( temp->left && temp->right && temp->info != item )
{
if ( temp->info > item )
{
// your ancestor stuff
temp = temp->left;
}
else if ( temp->info < item )
{
// your ancestor stuff
temp = temp->right;
}
}
If there's another way im all ears!
考虑:
a) 将 "vector of TreeNodes" 作为第二个参数传递给 Ancestors() 方法。
b) 在递归搜索期间(我首先使用深度),在向量中使用 push_back 以在搜索期间捕获访问的祖先(节点*),
c) 并且当找到值时,return 感兴趣的祖先。
d) 如果未找到(在当前分支中),请在 'de-cursion' 期间使用 pop_back 删除不需要的祖先节点。
我使用该技术找到了总和为目标的节点。
示例输出:(搜索总和为 -5 的节点)
BTree_t::dfVisitSum(-5)
@ level 3: -2 -3
@ level 2: 0 -2 -3
在树中:(即测试输入)
BTree_t::showTallView(): (balance: 0 sz: 19)
-3
-2
-1
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
42
// target-sum-search
int Node_t::sumSearch(const int targetSum, NVec_t& nodeLog)
{
int reportCount = 0;
// diag only std::cout << " Node_t::sumSearch() " << m_payLoad << std::endl;
// CAPTURE visit to log
nodeLog.push_back(this); // trace node route (depth-first-search style)
if(m_left)
{
reportCount += m_left->sumSearch(targetSum, nodeLog); // RECURSE
}
{
size_t startLvl = nodeLog[0]->m_lvl; // used in report
int accumulateSum = 0;
for (size_t i = 0; i < nodeLog.size(); ++i)
accumulateSum += nodeLog[i]->m_payLoad;
if (targetSum == accumulateSum)
{
std::stringstream reportLabelSS;
reportLabelSS << "\n @ level " << startLvl << ":";
std::cout << showNVec(nodeLog, reportLabelSS.str());
reportCount += 1;
}
}
if(m_right)
{
reportCount += m_right->sumSearch(targetSum, nodeLog); // RECURSE
}
// REMOVE this node visit from log
nodeLog.pop_back(); // removes last nodeLog element // DE-CURSE
return(reportCount); // report count
}
我一直在思考如何使用递归来检查树中的下一个值,如果它每次都被设置为根的话。
这是一个简单的解决方案的常见错误。 (但如果您不能添加方法,则可能不会)
本质上,您试图在一个函数中做太多事情。
简单的解决方案是将当前函数拆分为 2 个函数,
a) 处理从哪里开始搜索的初始化,它不是递归的,
b) 和另一个执行递归的。
我希望以下内容能为您提供足够的提示(因为我没有使用模板)
template <class ItemType>
string TreeType<ItemType>::Ancestors(ItemType item) const
{
string out = AncestorsR(item, root) // invoke recursive funct
return out;
}
template <class ItemType>
string TreeType<ItemType>::AncestorsR(ItemType item,
TreeNode<ItemType>* temp) const
{
string out="";
if(temp==nullptr || temp->info==item)
{
return "Value has no ancestors";
}
else
{
if(temp->info>item)
{
out+=temp->info;
temp=temp->left;
TreeType<ItemType>::Ancestors(temp->info);
}
if(temp->info<item)
{
out+=temp->info;
temp=temp->right;
TreeType<ItemType>::Ancestors(temp->info);
}
}
return out;
}