在只有节点值的二叉树中查找节点的祖先

Finding the ancestors of a node in a binary tree with only the value of a node

本文关键字:节点 查找 祖先 二叉树      更新时间:2024-04-28

我正在尝试完成一个接受值的方法,我必须递归地在二叉树中找到具有匹配值的节点的祖先,到目前为止,我在递归部分遇到了一点麻烦,下面是我使用的类:

#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变量设置为根,我就一直在思考如何使用递归来检查树中的下一个值。如果还有别的办法,我会洗耳恭听的!

我一直在思考如何使用递归来检查树中的下一个值,如果它每次都被设置为root的话。


这是一个简单解决方案的常见错误。(但如果你不能添加方法,可能不会(

从本质上讲,你试图在一个函数中做太多的事情。

简单的解决方案是将您当前的功能拆分为两个功能,

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

您可以像以前一样简单地初始化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;
}
}

如果还有其他方法,我会洗耳恭听的!

考虑:

a( 将"vector of TreeNode"作为第二个参数传递到Ancestors((方法中。

b( 在递归搜索过程中(我使用深度优先(,在向量中使用push_back来捕获搜索过程中访问的祖先(节点*(,

c( 当找到值时,返回感兴趣的祖先。

d( 如果未找到(在当前分支中(,请在"去草书"过程中使用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
}