有没有人知道用下面的方式合并树节点的算法?
treeA
   \ child a
          \node(abc)
   \ child b
          \node(xyz)                   
         + 
treeB
   \ child a              
          \node(qrs)
   \ child b
          \node(xyz)
               \node(pdq)
   \ child c
          \node(pdq)
         = // do merge
treeMerged     
   \ child a
          \node(abc) 
          \node(qrs)
   \ child b
          \node(xyz)
               \node(pdq)
   \ child c
          \node(pdq)任何帮助都将不胜感激。
发布于 2009-05-28 20:03:11
好吧,一旦我真的花时间去思考它,解决方案被证明比我预期的简单得多。(我已经发布了下面代码的关键部分)
   private TreeNode DoMerge(TreeNode source, TreeNode target) {
        if (source == null || target == null) return null;
        foreach (TreeNode n in source.Nodes) {
            // see if there is a match in target
            var match = FindNode(n, target.Nodes); // match paths
            if (match == null) { // no match was found so add n to the target
                target.Nodes.Add(n);
            } else { 
                // a match was found so add the children of match 
                DoMerge(n, match);
            }
        }
        return target;
    }还有兴趣知道是否有人有更好的解决方案吗?
发布于 2009-05-15 00:16:21
好吧,我承认,当我第一次开始处理它的时候,我没有想到它会太难,所以我想我会试着用LINQ来做。它被证明是疯狂的,但它是有效的。我相信有更优雅、更高效的算法,但它就在这里!
首先,我在TreeNodeCollection类上有一个ToEnumerable扩展方法:
    public static class TreeNodeCollectionExtensions
    {
        public static IEnumerable<TreeNode> ToEnumerable(this TreeNodeCollection nodes)
        {
            foreach (TreeNode node in nodes)
            {
                yield return node;
            }
        }
    }然后,我实现了一个自定义比较器:
公共类TreeNodeComparer : IEqualityComparer {
public bool Equals(TreeNode x, TreeNode y)
{
    return x.Text == y.Text;
}
public int GetHashCode(TreeNode obj)
{
    return obj.Text.GetHashCode();
}}
最后,疯狂:
private TreeView MergeTreeViews(TreeView tv1, TreeView tv2)
{
    var result = new TreeView();
    foreach (TreeNode node in tv2.Nodes)
    {
        result.Nodes.Add(node.Clone() as TreeNode);
    }
    foreach (TreeNode node in tv1.Nodes)
    {
        var nodeOnOtherSide = result.Nodes.ToEnumerable()
            .SingleOrDefault(tr => tr.Text == node.Text);
        if (nodeOnOtherSide == null)
        {
            TreeNode clone = node.Clone() as TreeNode;
            result.Nodes.Add(clone);
        }
        else
        {
            var n = node.Nodes.ToEnumerable()
                     .Where(t => !(nodeOnOtherSide.Nodes.ToEnumerable()
                     .Contains(t, new TreeNodeComparer())));
            foreach (TreeNode subNode in n)
            {
                TreeNode clone = subNode.Clone() as TreeNode;
                nodeOnOtherSide.Nodes.Add(clone);
            }
        }
    }
    return result;
}我的编码方式是它返回第三个“合并”的treeView。您可以更改代码,使其接受第三个treeview作为参数,这样您就可以传入可能已有的treeView。
再说一次,我相信有更好的方法可以做到这一点,但它应该是可行的。
还有一件事我想指出的是,这只适用于两层深度的TreeView。
发布于 2012-06-22 06:02:43
我想出了这个递归示例,在C#中非常好用(我自己一直在使用它),请注意,您需要找到一种方法将TreeNode.Nodes转换为数组:
public static TreeNode[] mergeTrees(TreeNode[] target, TreeNode[] source)
        {
            if (source == null || source.Length == 0)
            {
                return target;
            }
            if (target == null || target.Length == 0)
            {
                return source;
            }
            bool found;
            foreach (TreeNode s in source)
            {
                found = false;
                foreach (TreeNode t in target)
                {
                    if (s.Text.CompareTo(t.Text) == 0)
                    {
                        found = true;
                        TreeNode[] updatedNodes = mergeTrees(Util.treeView2Array(t.Nodes), Util.treeView2Array(s.Nodes));
                        t.Nodes.Clear();
                        t.Nodes.AddRange(updatedNodes);
                        break;
                    }
                }
                if (!found)
                {
                    TreeNode[] newNodes = new TreeNode[target.Length + 1];
                    Array.Copy(target, newNodes, target.Length);
                    newNodes[target.Length] = s;
                    target = newNodes;
                }
            }
            return target;
        }https://stackoverflow.com/questions/866380
复制相似问题