繁体   English   中英

创建一元树

[英]Creating a n-ary tree

我正在尝试创建带有孩子矢量的n元树。

这就是我到目前为止所得到的。

在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;
   }

这显然行不通。 我的主要问题是我不太确定如何为孩子们处理载体。 我是根据一些在线教程编写的,但是您可以看到我非常困惑。

代码中的主要(也是唯一可能的)问题是,您定义了Node类以通过指针( Node* )来操作节点:

class Node{
  private: 
    Node *parent; 
    vector <Node*> children;

但是您的方法是通过值( Node )来操作节点。

作为实例,在构造函数中:

Node::Node(Node parent, vector<Node> children){
    this->parent = &parent;

存储参数的地址将不起作用,它是一个临时对象,您需要将Node* parent对象传递给构造函数或创建一个新的Node对象。

    this->children = &children; 

这没有任何意义,因为this->childrenNode*的向量,而children参数是Node的向量。 同样,您需要将Node*的向量传递给构造函数或创建新的节点对象。

您在SetChildrenAddChildren有相同的问题。

另外,由于您将节点作为指针进行操作, 因此请注意内存管理 C ++中没有垃圾收集器,您必须在适当的时候delete所有new

检查以下代码是否可以帮助您创建n数组树。

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;
}

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层的节点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM