我试图为海上导航算法实现一些基本的树结构。 我有这样的事情:
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级递归树,但只创建一个级别的树。 我认为这是父指针的问题,但我无法意识到真正发生的事情。
答案 0 :(得分: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
的析构函数,泄漏了分配给节点的所有内存。当避免那些指针有利于对象时,这个问题就消失了。无论如何,在堆上分配Node
,这是用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);
}
}
}