我试图制作一个有多个孩子的树,这棵树应该看起来如下:
n
/ | \
n2 n3 n4
|
n5
每个节点都有自己的因素,我的任务是计算所有节点的数量,例如n5的数量是n.factor * n2.factor * n5.factor。
我认为问题在于指针,但我不知道如何处理它。
关于可能出错的一些想法在下面的代码中。
Obiekt.h
#include <string>
using namespace std;
class Obiekt
{
private:
string name;
public:
Obiekt();
Obiekt(string name);
void wyswietlObiekt();
string getName();
~Obiekt();
};
Node.h:
#include "Obiekt.h"
#include <vector>
#include <string>
using namespace std;
class Node {
public:
Node();
Node(Obiekt ob, double factor);
void add(Node node);
void show();
vector<Node> getChildrenList();
double getFactor();
Obiekt getObiekt();
private:
vector<Node> children;
double factor;
Obiekt obiekt;
};
Node.cpp:
#include "Node.h"
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <cstdlib>
using namespace std;
Node::Node()
{
obiekt = Obiekt();
factor = 0.0;
}
Node::Node(Obiekt ob, double mn)
{
obiekt = ob;
factor = mn;
}
void Node::show()
{
for (int i = 0; i < children.size(); i++) {
cout << children[i].getFactor() << endl;
}
}
void Node::add(Node node)
{
children.push_back(node);
}
vector<Node> Node::getChildrenList()
{
return children;
}
double Node::getFactor()
{
return factor;
}
Obiekt Node::getObiekt()
{
return obiekt;
}
tree.h中:
#include <string>
#include <vector>
#include "Node.h"
using namespace std;
class Tree
{
public:
Tree();
void addNode(Node *parent, Obiekt o, double mnoznik);
void addNode(Node *parent, Node wezel);
void deleteTree();
double countNodes(Node node, string key);
vector<Node*> getList();
double search(string key);
private:
vector<Node*> nodeTree;
Node root;
};
和Tree.cpp:
#include "Tree.h"
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <cstdlib>
using namespace std;
Tree::Tree()
{
root = Node();
}
void Tree::addNode(Node *parent, Obiekt o, double mnoznik)
{
Node n(o, mnoznik);
nodeTree.push_back(&n);
if (parent == NULL)
{
root = Node(o, mnoznik);
cout << "mnoznik korzenia: " << root.getFactor() << endl;
}
else
{
parent->add(n);
}
}
void Tree::addNode(Node *parent, Node wezel)
{
nodeTree.push_back(&wezel);
if (parent == NULL)
{
root = wezel;
cout << "mnoznik korzenia: " << root.getFactor() << endl;
}
else
{
parent->add(wezel);
cout << "added: " << wezel.getFactor() << endl;
}
}
double Tree::countNodes(Node node, string key)
{
int rozmiar = nodeTree.size();
double factor = node.getFactor();
double iloczynTemp = 1.0;
double quantity = 0.0;
for (Node node : node.getChildrenList())
{
iloczynTemp = factor * node.getFactor();
if (node.getObiekt().getNazwa() == key)
{
quantity = quantity + iloczynTemp;
}
quantity = quantity + countNodes(node, key);
}
return quantity;
}
double Tree::search(string key)
{
double wynik = 0.0;
for (Node *n : nodeTree)
{
if (n->getObiekt().getNazwa() == key)
{
wynik = wynik + n->getFactor();
}
}
return wynik;
}
void Tree::deleteTree()
{
nodeTree.clear();
}
vector<Node*> Tree::getList()
{
return nodeTree;
}
int main()
{
Tree tree;
Node n(Obiekt("n"), 1.0);
tree.addNode(NULL, n);
Node n2(Obiekt("n2"), 2.0);
tree.addNode(&n, n2);
Node n3(Obiekt("n3"), 3.0);
tree.addNode(&n, n3);
Node n4(Obiekt("n4"), 4.0);
tree.addNode(&n, n4);
Node n5(Obiekt("n5"), 5.0);
tree.addNode(&n2, n5);
n.show();
cout << n.getChildrenList().size() << endl;
cout << n2.getChildrenList().size() << endl;
cout << n.getChildrenList()[0].getChildrenList().size() << endl;
system("pause");
return 0;
}
问题出现在main()
中cout << n.getChildrenList().size() << endl; // right result = 3
cout << n2.getChildrenList().size() << endl; // right result = 1
cout << n.getChildrenList()[0].getChildrenList().size() << endl; // wrong result, should be 1 like above, but it is 0, why?
另一个问题是Tree.cpp中的countNodes方法:
quantity = quantity + countNodes(node, key); // why countNodes(node, key) is 0, it should be 0 when node don't have children, but some of them has.
提前谢谢你,bakii!
答案 0 :(得分:2)
我在此代码中看到的最大问题是您正在混合指针和按值传递的项目。一个不好的例子:
void Tree::addNode(Node *parent, Obiekt o, double mnoznik)
{
Node n(o, mnoznik);
nodeTree.push_back(&n);
...
在此行中,您将在addNode()函数的上下文中在堆栈上创建一个本地对象,然后将其地址推送到向量中。在此功能结束时, n 将超出范围,地址将不再有效。很可能在随后的调用中,地址将被重用,但是您在未定义的行为中退出,并且Nothing Good可以来自它。
对于这种结构,您可能希望一直使用指针。不要像这样在堆栈上分配节点,而是需要类似的东西:
Node* n = new Node(o, mnoznik);
nodeTree.push_back(&n);
在析构函数中,您需要删除向量中的所有节点。
通过更多的工作,你可以提出一个基于全值的树,或者能够使用智能指针来处理你的内存管理,但我称之为超出这个问题的范围。