草庐IT

c++ - 二叉树遍历以枚举斐波那契值的所有排列

coder 2024-02-24 原文

作为兴趣,我正在继续从事这个项目,并不断回来...

我要创建的是一种算法,用于枚举斐波那契值二叉树的值集:

我用来打印这棵树的排列的算法:

  1. 打印根值(结果:([root 0]=5))
  2. 传给左 child [left 1]
  3. 打印新的左节点[left 1]和右兄弟节点值(结果:([left 1] 3,[right 1] 2))
  4. 如果右兄弟节点[right 1]有子节点,遍历这个右节点[right 1],枚举它的值,连同它的兄弟左节点[left 1] (Result: [left 1] 3,[left 3] 1,[右 3] 1)
  5. 下降到左 child [left 2],作为第 2 步
  6. 打印新的左节点值[left 2] 2,以及公共(public)左父节点[left 1]的右兄弟节点值[right 2] 1;同时遍历枚举根的右节点每一层的结果。所以在关于树的例子中,枚举的结果是,遍历树得到排列:([left 2] 2,[right 2] 1,[right 1] 2),([left 2] 2,[right 2] 1, [左 3] 1, [右 3] 1))
  7. 没有留下的 child 可以继承,所以停止

每组加起来应该等于根的值。我认为我尝试描述算法中每个步骤的方法可能并不完全清楚 - 任何有关编写算法步骤的最佳实践的帮助对我也很有用。

我在这里期望的结果,枚举上面的树将是:

([根 0] 5),([左 1] 3, [右 1] 2),([左 1] 3, [左 3] 1, [右 3] 1),([左 2] 2,[右2]1,[右1]2),([左2]2,[右2]1,[左3]1,[右3]1)

我想采用递归方法并将其作为一种方法合并到我创建的构建树的二进制结构类中。所以这不是关于构建树结构,而是按照上面的方法遍历它,或者产生相同结果的方法。

谁能进一步帮助我?任何帮助将不胜感激。

在我的 `FibTree` `Class` 中添加设置打印方法:

FibTree 头文件(代码片段):

class FibTree {

public:
    class Node {
    public:
    int data;
        Node const* left;
        Node const* right;
        Node const* parent;
        int n;
        int level;
        int index;

        Node (void);

    };

    Node const* root; // 'root' pointer to constant Node
    FibTree (int);
    Node const* getRoot(void);

    void startWriteSets(Node const* root); // Write all sets of tree

private:
    static Node* buildTree( int n, int level = 0, int i = 1, Node* parent = NULL );
    // Used by startWriteSets
    void writeSets(std::vector<Node const*> &setsList, Node const* cur);

FibTree CPP 文件(代码片段):

// FibTree Constructor
FibTree::FibTree(int n) {
    this->root = buildTree( n );
};

// Getters
FibTree::Node const* FibTree::getRoot(void) {
    return this->root;
}

// Write sets of tree
void FibTree::startWriteSets(Node const* root) {
    std::vector<Node const*> setsList;
    std::cout << root->data;
    writeSets(setsList, root);
}

// Private FibTree methods
FibTree::Node* FibTree::buildTree( int n, int level, int i, Node* parent ) { // Build Tree structure
    Node* thisNode = new Node();
    thisNode->n = n;
    thisNode->level = level;
    thisNode->index = i;
    thisNode->parent = parent;
    if (n < 2) {
         thisNode->left = NULL;
         thisNode->right = NULL;
         thisNode->data = n;
         return thisNode;
    } else {
         thisNode->left = buildTree( n - 1 , level + 1, i*2, thisNode );
         thisNode->right = buildTree( n - 2, level + 1, i*2+1, thisNode );
         thisNode->data = thisNode->left->data + thisNode->right->data;
         return thisNode;
    }
}

void FibTree::writeSets(std::vector<Node const*> &setsList, Node const* cur) {
    std::vector<Node const*>::iterator nodeIterator;

    // Displays all preceding left values
    for (nodeIterator = setsList.begin();
        nodeIterator != setsList.end(); nodeIterator++) {
        std::cout << *nodeIterator->data;
    }   
    std::cout << cur->left->data;
    std::cout << cur->right->data;

    setsList.push_back(cur->left);
    writeSets(setsList,cur->right);
    setsList.pop_back();
}


// FibTree Node constructor
FibTree::Node::Node()
: data( 0 ),
left( NULL ),
right( NULL ),
parent( NULL ),
n( 0 ),
level( 0 ),
index( 0 )
{
};

我在 std::cout << *nodeIterator->data; 上遇到编译错误在 void FibTree::writeSets 内报告:

_error: request for member 'data' in '* nodeIterator. __gnu_cxx::__normal_iterator<_Iterator, _Container>::operator-> with _Iterator = const FibTree::Node**, Container = std::vector >', which is of non-class type 'const FibTree::Node*'

非常感谢任何帮助追踪此错误的人!

最佳答案

这里的问题不是您需要遍历 B 树。这是相当简单的。您遇到的问题是您需要跟踪等式另一半的状态。也就是说,当您下降到右链的第二层时,您仍然需要知道 [left 1] = 3。

一个可能的解决方案是跟踪 vector (或其他结构)中的左节点。这样....

void start(void) {
  vector<NODE*> list;
  cout << head->val;
  visit(list, head);
}

void visit(vector<NODE*> &list, NODE *cur) {
  // Displays all preceding left values.
  for (vector<NODE*> it = list.begin(); it != list.end(); it++) {
    cout << *it->val;
  }
  cout << cur->left->val;
  cout << cur->right->val;

  list.push_back(cur->left);
  visit(list, cur->right);
  list.pop_back();
}

这会在正确的方向上为您提供所需的信息。您需要添加适当的安全检查和其他方向,但这应该可以让您继续前进。

关于c++ - 二叉树遍历以枚举斐波那契值的所有排列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23708964/

有关c++ - 二叉树遍历以枚举斐波那契值的所有排列的更多相关文章

  1. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  4. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  5. ruby - Chef Ruby 遍历 .erb 模板文件中的属性 - 2

    所以这可能有点令人困惑,但请耐心等待。简而言之,我想遍历具有特定键值的所有属性,然后如果值不为空,则将它们插入到模板中。这是我的代码:属性:#===DefaultfileConfigurations#default['elasticsearch']['default']['ES_USER']=''default['elasticsearch']['default']['ES_GROUP']=''default['elasticsearch']['default']['ES_HEAP_SIZE']=''default['elasticsearch']['default']['MAX_OP

  6. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  7. ruby - 如何遍历 Ruby 中所有正则表达式匹配的字符串? - 2

    我们有一个字符串:“”这个正则表达式://i如何从当前字符串中获取所有匹配项? 最佳答案 "".scan(//)参见scan在ruby​​-docs上 关于ruby-如何遍历Ruby中所有正则表达式匹配的字符串?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/6857852/

  8. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  9. ruby - 引用具有指定索引的枚举器值 - 2

    假设我有一个可枚举对象enum,现在我想获取第三个项目。我知道一种通用方法是转换成数组,然后使用索引访问,如:enum.to_a[2]但这种方式会创建一个临时数组,效率可能很低。现在我使用:enum.each_with_index{|v,i|breakvifi==2}但这非常丑陋和多余。执行此操作最有效的方法是什么? 最佳答案 你可以使用take剥离前三个元素,然后剥离last从take给你的数组中获取第三个元素:third=enum.take(3).last如果您根本不想生成任何数组,那么也许:#Ifenumisn'tanEnum

  10. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

随机推荐