【问题标题】:Change/navigate to specific node of a tree?更改/导航到树的特定节点?
【发布时间】:2016-01-24 16:29:52
【问题描述】:

我正在尝试更改树的特定节点,但我被难住了。我知道可以获取和返回树中节点的算法,但我的目标是实际更改该树中节点的值。

例如,如果我们有一棵树,其中每个项目都有一个 Name 属性

Root
+Node 1
++Node 1_1
++Node 1_2
++...
+Node 2
++Node 2_1
++Node 2_2
++..

我想更改 Node 1.2 的名称,我会这样: Root.Node1.Node1_2.Name = "New Name"; 但是我将如何以编程方式执行此操作? 在我的例子中,我得到了对象节点 1_2,我想在树中更改它。


我忘了提到我使用的数据结构是我自己的数据结构,它有一个父级和一个子级列表。

我应该重新表述我想要实现的目标。给定上面的树结构(它可以是无限的深度,虽然没有说明),并且给定一个已知在树中的任意对象,我将如何访问树中的元素并修改它?也就是说,我将如何以编程方式实现类似于:Root.Node 1.Node 1_1.Node 1_1_2.Node 1_1_2_4.Node 1_1_2_N.Name?

如果还有什么困惑,请告诉我?

【问题讨论】:

  • 我们在说什么?树视图?你的目标是什么:Winforms? WPF? ASP? ...?? 总是相应地标记您的问题! - TreeNodes 有属性节点,它有一个字符串索引器。
  • @TaW 嗨。不,我只是在使用我自己的数据结构,它有一个 List Child 和一个 T parent。
  • 好吧,在这种情况下,您需要提供必要的方法。我的回答中 TreeNode 的索引器看起来不错,但您必须决定是否喜欢它。如果你这样做了,那么你应该为你的节点类实现一个索引器。 (我希望它是一个类,而不是一个结构 ;-)
  • 嗨@TaW 如果我事先不知道我想要查看的内容的深度怎么办? (请参阅我编辑过的帖子)在 C++ 中,我可以只使用一个指向对象的指针,然后从那里修改它,但我想不出在 C# 中这样做的好方法
  • 好吧,您可以通过在Dictionary<string, yourNodeClass> 中添加引用来跟踪所有节点。这几乎包含命名指针。当然,名称必须是唯一的,或者,如果您存储完整路径,则该路径必须是唯一的。如果您想在示例中使用 namig 方案,我会选择前者。虽然这听起来不像树,但任何插入都会把它搞砸。顺便说一句,c# 索引器背后没有魔法,你可以自己写;但它们仍然必须通过某种搜索算法来实现。

标签: c# algorithm tree


【解决方案1】:

如果你的意思是Winforms TreeViews,每个TreeNode 都有一个Nodes 属性和一个字符串indexer 你可以使用,提供你已经设置并知道Node 名称/键:

TreeView tv = new TreeView();
tv.Nodes.Add("a", "Albert");
tv.Nodes["a"].Nodes.Add("v", "Victoria");

tv.Nodes["a"].Nodes["v"].Text = "Peggy";

请注意,您甚至可以更改这些名称/键,新值现在可以使用:

tv.Nodes["a"].Name = "Al";
tv.Nodes["Al"].Text = "Bundy";

当然现在旧的不行了:

tv.Nodes["a"].Text = "Bud"; // <-- now throws a NullObjectReference!

【讨论】:

    【解决方案2】:

    这是我想出的解决方案,但我觉得应该有一种更优雅的方式来做到这一点。

        public static void Rename(Node the_node, string new_name)
        {
                List<Node> parent_list = new List<Node>();
                Node current_node = the_node;
                parent_list.Add(current_node);
                while (current_node.ParentNode != null)
                {
                    parent_list.Add(current_node.ParentNode);
                    current_node = the_node.ParentNode;
                }
    
                Rename(ref the_node, parent_list, new_name);
        }
    
        private static void Rename(ref Node target_node, List<Node> traverse_order, string new_name)
        {
            if (traverse_order.Count > 0)
            {
                Node current_node = traverse_order.Last();
                traverse_order.RemoveAt(traverse_order.Count - 1);
    
                EditNode(ref current_node, traverse_order);
            }
            else
            {
                target_node.Name = new_name;
            }
        }
    

    【讨论】:

    • 这绝对令人困惑。 LIsts.IndexOfEditNode 是什么?如果您已经引用了要更改的节点(第一种方法中的Node the_node 参数),那么为什么不能简单地更改其名称:the_node.Name = new_name?你为什么要关心节点的祖先?
    猜你喜欢
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多