我正在尝试使用子项向量创建一个n-ary树。
这是我到目前为止所得到的。
在node.h文件中我有:
#include <vector>
#include <string>
using namespace std;
class Node{
private:
Node *parent;
vector <Node*> children;
int data;
public:
Node();
Node(Node parent, vector<Node> children);
Node(Node parent, vector<Node> children, int data);
Node * GetParent();
void SetChildren(vector<Node> children);
vector<Node>* GetChildren();
void AddChildren(Node children);
void SetData(int data);
int GetData();
bool IsLeaf();
bool IsInternalNode();
bool IsRoot();
};
这是我的node.cpp文件。
#include "node.h"
Node::Node(){
this->parent = NULL;
this->children = NULL;
this->data = 0;
}
Node::Node(Node parent, vector<Node> children){
this->parent = &parent;
this->children = &children;
}
Node::Node(Node parent, vector<Node> children, int data){
this->parent = &parent;
this->children = &children;
this->data = data;
}
Node* Node:: GetParent(){
return this->parent;
}
void Node::SetChildren(vector<Node> children){
this->children = &children;
}
vector<Node> * Node::GetChildren(){
return this->children;
}
void Node::AddChildren(Node children){
this->children.push_back(children);
}
void Node::SetData(int data){
this->data = data;
}
这显然不起作用。我的主要问题是我不太确定如何为孩子们处理矢量。我在网上的一些教程后写了这篇文章,但你可以看到我非常困惑。
答案 0 :(得分:4)
代码中的主要(也可能是唯一)问题是您定义了Node
类来按指针操作节点(Node*
):
class Node{
private:
Node *parent;
vector <Node*> children;
但您的方法是按值(Node
)操作节点。
例如,在构造函数中:
Node::Node(Node parent, vector<Node> children){
this->parent = &parent;
存储父参数的地址不起作用,它是一个临时对象,您需要将Node* parent
传递给构造函数或创建新的节点对象。
this->children = &children;
这没有任何意义,因为this->children
是Node*
的向量,children
参数是Node
的向量。同样,您需要将Node*
的向量传递给构造函数或创建新的节点对象。
您在SetChildren
和AddChildren
中遇到了同样的问题。
此外,由于您将节点作为指针进行操作,要非常小心内存管理。在C ++中没有垃圾收集器,你必须delete
在new
和适当的时间{{1}}。
答案 1 :(得分:2)
检查以下代码是否有助于您创建n-array树创建。
struct TreeNode
{
vector<TreeNode*> children;
char value;
};
class TreeDictionary
{
TreeNode *root;
public:
TreeDictionary()
{
root = new TreeNode();
root->value = 0;
}
TreeNode *CreateNode(char data)
{
TreeNode *parent_node = new TreeNode;
if (parent_node)
parent_node->value = data;
return parent_node;
}
TreeNode* SearchElement(TreeNode *NextNode, char *data, int& val)
{
bool bVal = false;
for (vector<TreeNode*>::iterator it = NextNode->children.begin(); it != NextNode->children.end(); it++)
{
if ((*it)->value == *(data))
return SearchElement((*it), ++data, ++val);
}
return NextNode;
}
TreeNode *InsertNode(TreeNode *parent, TreeNode *ChildNode, char data)
{
if (parent == NULL)
ChildNode = CreateNode(data);
else
{
TreeNode *childNode = CreateNode(data);
parent->children.push_back(childNode);
return childNode;
}
return ChildNode;
}
void InsertMyString(string str)
{
TreeNode *NextNode = root;
for (int i = 0; i < str.size(); i++)
{
if (str[i] == '\0')
return;
cout << str[i] << endl;
if (NextNode->value == 0)
{
NextNode->value = str[i];
continue;
}
else if (NextNode->value != str[i])
{
NextNode = InsertNode(NextNode, NULL, str[i]);
}
else
{
TreeNode *node;
node = SearchElement(NextNode, &str[++i], i);
NextNode = InsertNode(node, NULL, str[i]);
}
}
}
};
int main()
{
TreeDictionary td;
td.InsertMyString("Monster");
td.InsertMyString("Maid");
td.InsertMyString("Monday");
td.InsertMyString("Malli");
td.InsertMyString("Moid");
return 0;
}
答案 2 :(得分:0)
SearchElement
的此实现(无递归)也可以工作:
TreeNode* SearchElement(TreeNode *NextNode, char *data, int& val)
{
bool bVal = false;
for (vector<TreeNode*>::iterator it = NextNode->children.begin(); it != NextNode->children.end(); it++)
{
if ((*it)->value == *(data))
return (*it);
}
return NextNode;
}
TreeNode* res = SearchElement(root, data, value);
我检查了一下,这是无法理解的,为什么-它适用于您想要在树中找到的任何节点,无论树中节点的深度和级别如何,而且尚不清楚原因,因为循环仅迭代在树第二层的子节点(根节点的子节点)上,尽管如此-它甚至会在树中找到深度为10层的节点。