在仅包含节点值的二叉树中查找节点的祖先

时间:2020-04-30 19:47:38

标签: c++ data-structures binary-tree ancestor

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

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

}

如果每次都只是将其设置为root,那么我将如何使用递归检查带有temp变量的树中的下一个值。如果还有别的办法,我会全然倾听!

3 个答案:

答案 0 :(得分:0)

除了进行递归操作外,您还可以像以前一样简单地初始化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;
    }
}

答案 1 :(得分:0)

如果还有另一种方法!

考虑:

a)将“ TreeNodes的向量”作为第二个参数传递到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
}

答案 2 :(得分:0)

如果每次都只是将其设置为root,我就无法使用递归检查带有temp变量的树中的下一个值。


这是使用简单解决方案的常见错误。 (但是,如果您不能添加方法,也许就不可以)

本质上,您正在尝试在一个函数中做太多事情。

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

a)处理从何处开始搜索的初始化,这不是递归的,

b)和另一个执行递归的操作。

我希望以下内容能为您提供足够的提示(因为我不熟悉模板)

const distinctBy = (prop, arr) => [...new Set(arr.map(o => o[prop]))]

const guests = [{"name":"Kiley","age":24},{"name":"Tom","age":36},{"name":"Jason","age":67},{"name":"Mike","age":24}]

const result = distinctBy('age', guests)

console.log(result)
相关问题