【问题标题】:Need help in n tree implementation在 n 树实现中需要帮助
【发布时间】:2013-02-08 21:59:48
【问题描述】:

我正在尝试使用 c# 实现 n 元类型的数据结构。树将有一个根节点和子数组,并且子数组中的每个子节点也将具有一组子节点。我想要做的是每当我们添加子数组时,该数组应该被添加到叶节点中存在的所有子节点中。我的代码是

      public void addChildren(Node root, Node[] children)
        {

             if (root.children == null)
            {
                root.children = children;

            }
            else
            {
                for (int i = 0; i < root.children.Length; i++)
                {

                    addChildren(root.children[i], children);
                }
            }

        }

主程序

     Dictionary<String, String[]> measurelist = new Dictionary<string, string[]>();
        String[] values = { "y", "n" };
        measurelist.Add("m1", values);
        measurelist.Add("m2", values);
        measurelist.Add("m3", values);           
        foreach (KeyValuePair<String, String[]> entry in measurelist)
        {
            Node[] children = new Node[entry.Value.Length];
           for(int i = 0; i < entry.Value.Length ;i ++)
            {
                Node child = new Node(entry.Key+":"+entry.Value[i]);
                children[i] = child;
            }

            clustertree.addChildren(clustertree.root, children);               
        }

但此代码会导致无限递归调用。我试过但无法弄清楚出了什么问题?请帮助我找出我做错了什么。 I have described the problem in the image

解决方案: 在您的帮助下,我找到了解决此问题的方法。如果我解释根本原因,我认为这将对可能面临同样问题的其他人有所帮助。 当我传递子节点数组时,问题的主要原因是作为引用而不是值传递。为了确保不会将相同的子数组引用传递给下一个递归调用,我对代码进行了一些更改。

这是我更正后的代码

 public void addChildren(Node root, Node[] children)
        {

             if (root.children == null)
            {

                root.children = children;

            }
            else
            {
                for (int i = 0; i < root.children.Length; i++)
                {                       
                    Node[] children1 = new Node[children.Length];
          //I am creating a new array and nodes and passing the newly created array to                                       the next recursive call
                    for (int j = 0; j < children.Length; j++)
                    {
                        Node node = new Node(children[j].key);                           
                        node.children = children[j].children;
                        children1[j] = node;
                    }
                    addChildren(root.children[i], children1);
                }
            }

        }

再次感谢:)

【问题讨论】:

    标签: c# recursion tree mutation


    【解决方案1】:

    您可能应该将您的内部node[] 变成list&lt;node&gt; 而不是数组。

    然后使用此代码

          public void addChildren(Node root, Node[] children)
            {
    
                if (root.children == null)
                {
                    root.children = new List<Node>();
    
                }
    
                root.children.AddRange(children);
    
            }
    

    【讨论】:

    • 感谢您的回复。如果我使用您的代码,我会得到一棵树,它的根有四个孩子。但是我需要一棵树,它的根有两个孩子,每个孩子又有两个孩子。在上面的场景中,我想要 root -> m1:y,m1:n 和 m1:y ->m2:y,m2:n ,m1:n -> m2:y,m2:n 等等
    • 很抱歉,当我发布我的答案时,您没有添加主程序
    【解决方案2】:

    您并没有像图中所示那样创建树,而是在执行以下操作:

           R
          / \
         /   \
        a1   a2 (children of this are actually b1 and b2)
       / \   
      /   \
     b1   b2
    

    当您将b1, b2 添加为a2 的子代时,您将引用已添加到a1 的相同b1 and b2

    在下一次迭代中,当您添加c1 and c2 时,根据您的算法,您首先通过a1c1 and c2 引用到b1 and b2,但是您的函数并没有在这里停止,这次它再次通过b1 and b2 a2,但由于 c1 and c2 已被添加为 b1 and b2 的子代,因此算法变得混乱并进入永久循环。

    解决这个问题:

    找到树的最后一层,但直到最后一层只使用递归路径,只使用一个孩子。

    public boolean addChildren(Node root, Node[] children)
    {
    
        if (root.children == null)
        {
            root.children = children;
            return true;
        }
        else
        {
            for (int i = 0; i < root.children.Length; i++)
            {
                /* if it returns true then it was last level 
                       else break */
                if(!addChildren(root.children[i], children)) 
                {
                    /* this is non-last level break */
                    break;
                }
            }
        }
        return false;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多