【问题标题】:Recursive binary tree class of Fibonacci sequence斐波那契数列的递归二叉树类
【发布时间】:2013-03-14 00:23:54
【问题描述】:

作为个人项目的一部分,而不是家庭作业 - 只是为了我自己的兴趣和 C++ 入门,我正在尝试创建一个斐波那契值的二叉树; 我知道我在这里犯了一些基本错误,但如果有人可以帮助我,我将不胜感激,我的代码如下:

#include <iostream>
#include <typeinfo>
using namespace std;

class FibTree {

    class Node {
    public:
        Node const* left;
        Node const* right;
        int value;
        Node (int, Node*, Node*);
    };

    Node const* root;

public:
    FibTree (int);
    int getValue(){
        return this->root->value;
    };

private:
    static Node* buildTree(int n ) {
        if (n < 2) {
            return new Node( n, NULL, NULL );
        } else {
            Node* left = buildTree( n - 1 );
            Node* right = buildTree( n - 2 );
            return new Node( left->value + right->value , left, right );
        }
    }
};
FibTree::FibTree(int n) {
    this->root = buildTree(n);
};

FibTree::Node::Node(int value, Node* left, Node* right){
    this->value = value;
    this->left = left;
    this->right = right;
};

int main () {
    FibTree f(6);
    cout << f.getValue();
    return 0;
}

谁能让我知道我在这里做错了什么,重要的是告诉我为什么我会收到错误'Cannot convert 'FibTree' to 'FibTree*' in assignment;以及我应该如何更好地处理?

提前致谢, 亚历克斯

【问题讨论】:

  • 整个实现是错误的;你需要从头开始重写代码。
  • this-&gt;left = new FibTree(n - 1, this); 是您修复错误的方法(以换取一些内存泄漏,但它们不会造成伤害)。但我同意你的看法:你犯了一堆根本性的错误。但我会把它留给希望构建完整答案的人:)

标签: c++ data-structures recursion binary-tree fibonacci


【解决方案1】:

正如错误消息所说,您正在尝试分配一个具体的 将FibTree 键入指针。在许多情况下,错误在于 您正在使用指针,但在这种情况下,身份很重要。 对于每个值,您需要一个且只有一个 FibTree 实例。

既然你的目标显然是学习好的做法,我会 首先指出你似乎是抽象的 在FibTree 中实现的不是树的实现,而是节点的实现 在树上。就个人而言,我会从一些东西开始 喜欢:

class FibTree
{
    class Node
    {
        Node const* left;
        Node const* right;
        int value;
    };
    Node const* root;
public:
    //  ...
};

在那之后,更多的是个人喜好的问题,你如何 想建树;重要的一点是每个节点 必须动态分配(new Node(...),而不仅仅是 Node(...)),并且 leftright 指针必须是 已经在树中的元素。

除此之外,我不确定你想让我告诉你多少, 解决剩下的可能是一个有趣的学习 经验,但如果您想要更多点击,请随时询问,并且 我将编辑此答案以提供它们。我想说的一件事: 我会向Node 添加一个构造函数。类似的东西 Node::Node( int value, Node* left, Node* right )。严格 说,你不需要它,它不会改变算法 无论如何,但它会使算法写得更多 简洁。另外,我会使用递归函数来构建 结构,从构造函数中调用。最后,我要添加一个 树级别的析构函数,递归遍历树 删除所有节点。

但我再说一遍:要掌握的最重要的一点是 节点不是树。

【讨论】:

  • 非常感谢您的建议;如果没问题,我会探讨你的观点并在有任何问题时回复你。亚历克斯
  • 嗨,James,我已经在嵌套的 Node 类中添加了,但是在声明 Node 类构造函数时遇到了问题:class FibTree { class Node { public: Node const* left; Node const* right; int value; Node (int, Node*, Node*); }; Node::Node (int value, Node* left, Node* right); public: ... italic_Cannot 的错误声明成员函数 'FibTree::Node::Node ' 在 'FibTree'_italic 你知道为什么会这样吗?谢谢亚历克斯
  • 如果您在类外定义FibTree::Node 的构造函数,则格式为FibTree::Node::Node(...)。另外:可以直接在Node的类定义中定义构造函数的实现,也可以在全局范围内定义,但不能在封闭类的范围内定义。 (我通常不喜欢直接在类定义中定义函数,但是对于嵌套类的几乎微不足道的构造函数,我会经常例外。)
  • 谢谢詹姆斯;考虑到这一点(并且经过一些试验和错误),在等待您的回复时,我解决了这个问题 - 所以这是我学到的其他东西。您建议调用递归函数从构造函数构建树 - 这将来自树构造函数,而不是节点构造函数?
  • @Alex2134 首先,我会将buildTree 设为私有。我可能会让它返回一个Node*。我只是快速浏览了代码,但我的印象是您的构建方向错误。类似于Node* buildTree( n ) { return n &lt; 2 ? new Node( n, NULL, NULL ) : new Node( n, buildTree( n - 1 ), buildTree( n - 2 ); } 的东西。在构造函数中,可以直接从buildTree初始化root,在初始化列表中(buildTree可以是static,因为它不需要this指针)。
【解决方案2】:
        this->left = FibTree(n - 1, this); // This line errors 'Cannot convert 'FibTree' to 'FibTree*' in assignment
        this->right = FibTree(n - 2, this); // This line errors 'Cannot convert 'FibTree' to 'FibTree*' in assignment

应该是

        this->left = new FibTree(n - 1, this);
        this->right = new FibTree(n - 2, this);

不知道为什么你将 root 传递给你的构造函数,你没有用它做任何事情。

【讨论】:

  • 显而易见的问题(对于有一些 OO 编程经验的人来说很明显)是他混淆了节点和树。我认为您的解决方案在这种情况下实际上可能有效,但只是偶然;如果你不牢记这两个概念之间的区别,你会在某个地方遇到问题。
猜你喜欢
  • 2012-03-03
  • 2016-02-21
  • 2011-07-27
  • 2012-11-19
  • 2016-11-07
  • 2012-02-16
  • 1970-01-01
  • 2010-12-03
相关资源
最近更新 更多