更改/导航到树的特定节点?

时间:2015-10-25 14:57:17

标签: c# algorithm tree

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

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

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mMapView = (MapView) findViewById(R.id.map);

    mMapView.setEsriLogoVisible(true);
    mMapView.enableWrapAround(true);

    WMTSLayer layer = new WMTSLayer("http://gis.sinica.edu.tw/tgos/wmts/1.0.0/WMTSCapabilities.xml");
    layer.layerInitialise();

    mMapView.addLayer(layer);
}

我想改变Node 1.2的名称,我会这样: Root +Node 1 ++Node 1_1 ++Node 1_2 ++... +Node 2 ++Node 2_1 ++Node 2_2 ++.. 但是我如何以编程方式执行此操作? 在我的例子中,我被赋予了对象节点1_2,我想在树中更改它。

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

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

如果仍有任何混淆,请告诉我?

2 个答案:

答案 0 :(得分: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!

答案 1 :(得分:1)

这是我提出的解决方案,但我觉得应该有更优雅的方式来做。

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