关于递归:在C#中遍历树的递归lambda表达式

关于递归:在C#中遍历树的递归lambda表达式

Recursive lambda expression to traverse a tree in C#

有人可以告诉我如何实现递归lambda表达式来遍历C#中的树结构。


好的,我终于找到了一些空闲时间。
我们开始:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class TreeNode
{
    public string Value { get; set;}
    public List<TreeNode> Nodes { get; set;}


    public TreeNode()
    {
        Nodes = new List<TreeNode>();
    }
}

Action<TreeNode> traverse = null;

traverse = (n) => { Console.WriteLine(n.Value); n.Nodes.ForEach(traverse);};

var root = new TreeNode { Value ="Root" };
root.Nodes.Add(new TreeNode { Value ="ChildA"} );
root.Nodes[0].Nodes.Add(new TreeNode { Value ="ChildA1" });
root.Nodes[0].Nodes.Add(new TreeNode { Value ="ChildA2" });
root.Nodes.Add(new TreeNode { Value ="ChildB"} );
root.Nodes[1].Nodes.Add(new TreeNode { Value ="ChildB1" });
root.Nodes[1].Nodes.Add(new TreeNode { Value ="ChildB2" });

traverse(root);

使用定点组合器是一个合适的解决方案,甚至是许多功能编程语言中惯用的解决方案。简而言之:定点组合器回答了以下问题:"我如何将匿名函数定义为递归?"。但是解决方案是如此简单,以致于撰写整篇文章来解释它们。

一个简单,实用的选择是在定义之前"回到过去" C:声明的滑稽动作。尝试以下操作("阶乘"功能):

1
2
Func<int, int> fact = null;
fact = x => (x == 0) ? 1 : x * fact(x - 1);

像吊饰一样工作。

或者,对于在类TreeNode上的对象的前序树遍历,该对象适当地实现了IEnumerable<TreeNode>来遍历其子级:

1
2
3
4
5
Action<TreeNode, Action<TreeNode>> preorderTraverse = null;
preorderTraverse = (node, action) => {
    action(node);
    foreach (var child in node) preorderTraverse(child, action);
};

A simple alternative is to"go back in time" to the antics of C and C++: declaration before definition. Try the following:

1
2
Func<int, int> fact = null;
fact = x => (x == 0) ? 1 : x * fact(x - 1);

Works like a charm.

是的,确实有效,但有一点警告。 C#具有可变的引用。因此,请确保您不会意外地执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Func<int, int> fact = null;
fact = x => (x == 0) ? 1 : x * fact(x - 1);

// Make a new reference to the factorial function
Func<int, int> myFact = fact;

// Use the new reference to calculate the factorial of 4
myFact(4); // returns 24

// Modify the old reference
fact = x => x;

// Again, use the new reference to calculate
myFact(4); // returns 12

当然,此示例有些虚构,但是在使用可变引用时可能会发生这种情况。如果您使用aku的链接中的组合器,则将不可能。


假设一个神话般的对象TreeItem,它包含一个Children集合来表示您的层次结构。

1
2
3
4
5
6
7
8
9
10
11
12
    public void HandleTreeItems(Action<TreeItem> item, TreeItem parent)
    {
        if (parent.Children.Count > 0)
        {
            foreach (TreeItem ti in parent.Children)
            {
                HandleTreeItems(item, ti);
            }
        }

        item(parent);
    }

现在可以调用它,通过将名称打印到控制台来传递处理一项的lambda。

1
HandleTreeItems(item => { Console.WriteLine(item.Name); }, TreeItemRoot);

推荐阅读

    正则表达式不包含

    正则表达式不包含,正则,数字,字符串,正则表达式,位置,下划线,正则表达式不管是做哪方面开发的朋友都会使用到,但是有好多人不太懂正则正则表达式

    PHP正则表达式合集

    PHP正则表达式合集,输入,正则表达式,验证,字符串,数字,字符,正则表达式,又称规则表达式,英文名为Regular Expression,在代码中常简写为regex、rege

    详解Javascript对象的5种循环遍历方法

    详解Javascript对象的5种循环遍历方法,属性,对象,遍历,方法,数组,键值,Javascript对象如何循环遍历?下面本篇文章给大家详细介绍5种JS对象遍历方

    递归函数代码示例

    递归函数代码示例,递归,函数,本文目录递归函数代码示例编写一个递归函数计算从1加到100的和c语言函数递归调用c语言类函数递归调用的简单

    php 正则表达式贪婪模式,非贪婪模式

    php 正则表达式贪婪模式,非贪婪模式,贪婪,模式,正则表达式匹配模式分为贪婪非贪婪两种。这两种模式是影响存在限定词修饰的子表达式的匹配

    php 正则表达式贪婪模式,非贪婪模式

    php 正则表达式贪婪模式,非贪婪模式,贪婪,模式,正则表达式匹配模式分为贪婪非贪婪两种。这两种模式是影响存在限定词修饰的子表达式的匹配

    js正则表达式

    js正则表达式,字符,正则表达式,字符串,模式,表达式,数字,  js正则表达式中有很多特殊的字符可能有些人并不知道是什么含义,下面我们就来具体介