【问题标题】:C++ pointers in tree structure树形结构中的 C++ 指针
【发布时间】:2017-03-23 12:40:28
【问题描述】:

我正在尝试为海上导航算法实现一些基本的树结构。 我有这样的东西:

class Point {
    float lng;
    float lat;
};

class Node {
public:
    Node *parent;
    std::list<Node> *childern;
    Point *point;
    Node::Node(Node *prnt, Point *point);
    void Node::calcChildrens();
};
Node::Node(Node *prnt, Point *point)  {
    this->parent = prnt;
    this->point = point;
    this->childern = nullptr;
}
int counter = 0;
void Node::calcChildrens() {

    for (int i = 0; i < 5; i++) {

        Point *p = new Point(someValX, someValY);
        Node n = Node(this, p);

        if (this->childern == NULL) this->childern = new list<Node>;
        this->childern->push_back(n);
        if (counter < 4) {
            counter++;
            n.calcChildrens();
        }
}

这应该创建 4 层递归树,但只创建一层树。 我认为这是父指针的问题,但我无法意识到真正发生了什么。

【问题讨论】:

  • 该代码没有做任何事情。请提供minimal reproducible example 即包含main 以使其成为工作示例
  • 还包括一个问题也不错
  • 您在Node::calcChildrens(){中没有匹配的{,请提供工作代码。

标签: c++ recursion constructor tree this


【解决方案1】:

您的代码有几个问题

struct Point {   // we want public access, hence struct not class
    float lng;
    float lat;
};

struct Node {    // if all members a public, use struct
    Node*parent = nullptr;             // provide default argument
    std::list<Node> children;          // hold a list, not a pointer to one
    Point point;                       // hold a Point, not a pointer to one
    Node(Node*p, const Point&x)
    : parent(p), point(x) {}           // use initialization list
    void calcChildren(size_t levels);  // avoid global variable counter; use correct English
};

void Node::calcChildren(size_t levels)
{
    if(levels--)
        for(int i = 0; i < 5; i++) {   // really 5? 4 children seems more logical
            // construct child in place, avoid copying a Node    
            children.emplace_back(this, Point{someValX, someValY});
            children.back().calcChildren(levels);
        }
}

您还可以将树深度作为每个节点的数据成员来跟踪。不幸的是,由于您未能提供Minimal Complete and Verifiable Example,因此我无法在此处进行测试。

另请注意,您的代码没有Node 的析构函数,从而泄漏了分配给节点的所有内存。当避免这些指针有利于对象时,这个问题就消失了。由于Nodes 无论如何都是在堆上分配的,因此这是 C++ 中合理且正确的处理方式。

进一步注意,您可能希望避免将子项保留在链表中(如果效率很重要,则应避免使用链表)。您可以改为使用数组或vector。在这种情况下

struct Node {    // if all members a public, use struct
    Node*parent = nullptr;             // provide default argument
    std::vector<Node> children;        // hold a vector, not a pointer to one
    Point point;                       // hold a Point, not a pointer to one
    Node(Node*p, const Point&x)
    : parent(p), point(x) {}           // use initialization list
    void calcChildren(size_t levels);  // avoid global variable counter; use correct English
};

void Node::calcChildren(size_t levels)
{
    if(levels--) {
        children.reserve(5);
        for(int i = 0; i < 5; i++) {
            // construct child in place, avoid copying a Node    
            children.emplace_back(this, Point{someValX, someValY});
            children.back().calcChildren(levels);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 2021-05-03
    • 2021-04-11
    相关资源
    最近更新 更多