C#高级语法:递归树的基本操作写法参考

目录

零、递归新三要素

一、根据ID求后代

二、加一个父节点

三、生成一个递归树


零、递归新三要素

1.入参是可递归的(例如)

        public class Person

        {

            //省略其他字段

            public List<Person> Children { set; get; }

        }

2.递归遍历父节点下的子节点
3.维护返回值,即满足条件要返回、最后结果要返回。

(注意:1.引用类型可直接修改其属性或字段无需返回值。2.在递归遍历引用类型属性时,需做判空处理,以防止空引用异常。)

一、根据ID求后代

using System.Text.Json;
using System.Text.Encodings.Web;

class MainClass
{
    static Person root = new Person(0, "全体人类")
    {
        Spring = new List<Person>
    {
        new Person(1, "苏家")
        {
            Spring = new List<Person>
            {
                new Person(3, "苏一"),
                new Person(4, "苏二"),
                new Person(5, "苏三")
                {
                    Spring = new List<Person>
                    {
                        new Person(6, "苏三仔")
                        {
                            Spring = new List<Person>
                            {
                                new Person(7, "苏三仔仔")
                            }
                        },
                    }
                },
                new Person(8, "苏三妹")
            }
        },
        new Person(2, "李家")
        {
            Spring = new List<Person>
            {
                new Person(9, "李一"),
                new Person(10, "李二")
                {
                    Spring = new List<Person>
                    {
                        new Person(11, "李二仔")
                    }
                }
            }
        }
    }
    };
    /// <summary>
    /// 递归:第一个参数是查找指定ID,第二个参数是传入需要查找的实体
    /// </summary>
    /// <param name="id"></param>
    /// <param name="tree"></param>
    /// <returns>结果:输出指定ID的个人信息及其个人的所有后代,否则返回null。</returns>
    public static Person FindTree(int id, Person tree)
    {
        if (tree.Id == id)//1.如果实体匹配则返回实体,跳到第三步
        {
            return tree;
        }
        if (tree.Spring != null)//2.如果实体有子节点,遍历子节点递归查找
        {
            foreach (var item in tree.Spring)
            {
                var foundTree = FindTree(id, item);
                if (foundTree != null)//3.找到了则中止递归
                {
                    return foundTree;
                }
            }
        }
        return null;//4.都找不到则返回空
    }
    static void Main(string[] args)
    {
        //1.打印出这棵树的结构
        string json = root.ToJson();
        //Console.WriteLine(json);

        //2.递归:第一个参数是查找指定ID,第二个参数是传入需要查找的实体
        //结果:输出指定ID的个人信息及其个人的所有后代
        //测试: 0 4 5 100
        var result_tree = FindTree(5, root);

        //3.打印输出
        if (result_tree!=null)
        {
            string json2 = result_tree.ToJson();
            Console.WriteLine(json2);
        }

    }
}
class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Person> Spring { get; set; }
    public Person(int id, string name)
    {
        Id = id;
        Name = name;
        Spring = new List<Person>();
    }
    public string ToJson()
    {
        var options = new JsonSerializerOptions
        {
            WriteIndented = true,
            Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
        };
        return JsonSerializer.Serialize(this, options);
    }
}

二、加一个父节点

using System.Collections.Immutable;
using System.Text.Encodings.Web;
using System.Text.Json;

class MainClass
{
    static Person root = new Person(0, "全体人类")
    {
        Spring = new List<Person>
    {
        new Person(1, "苏家")
        {
            Spring = new List<Person>
            {
                new Person(3, "苏一"),
                new Person(4, "苏二"),
                new Person(5, "苏三")
                {
                    Spring = new List<Person>
                    {
                        new Person(6, "苏三仔")
                        {
                            Spring = new List<Person>
                            {
                                new Person(7, "苏三仔仔")
                            }
                        },
                        new Person(8, "苏三妹")
                    }
                }
            }
        },
        new Person(2, "李家")
        {
            Spring = new List<Person>
            {
                new Person(9, "李一"),
                new Person(10, "李二")
                {
                    Spring = new List<Person>
                    {
                        new Person(11, "李二仔")
                    }
                }
            }
        }
    }
    };

    static void Main(string[] args)
    {
        //1.打印出这棵树的结构
        string json = root.ToJson();
        //Console.WriteLine(json);
        //2.添加父节点,本质将原结果添加到父节点的Spring中
        Person newTree = new Person(1000,"全体智慧生物");
        newTree.Spring.Add(root);
        //3.打印结果
        string json2 = newTree.ToJson();
        Console.WriteLine(json2);
    }

}
class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Person> Spring { get; set; }
    public Person(int id, string name)
    {
        Id = id;
        Name = name;
        Spring = new List<Person>();
    }
    public string ToJson()
    {
        var options = new JsonSerializerOptions
        {
            WriteIndented = true,
            Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
        };
        return JsonSerializer.Serialize(this, options);
    }
}

三、生成一个递归树

// 从列表中找到没有父节点的元素作为树的根节点,注意list是查库得到的List<ProManDayAnalysis>
ProManDayAnalysis model = list.FirstOrDefault(w => string.IsNullOrWhiteSpace(w.ParentAmoeba));

// 递归生成树,第一个参数是整个列表,第二个参数是根节点实体
BindTree(list, model);
    
private void BindTree(IList<ProManDayAnalysis> dateList, ProManDayAnalysis parentItem)
{
    // 找到当前节点的子节点集合
    var subItems = dateList.Where(w => w.ParentAmoeba == parentItem.AmoebaCode).ToList();
    if (subItems.Count != 0)//如果找到子节点
    {
        parentItem.Children = new List<ProManDayAnalysis>();
        parentItem.Children.AddRange(subItems);// 给父节点添加孩子
        foreach (var subItem in subItems)//遍历递归父节点的孩子,执行一样的操作
        {
            BindTree(dateList, subItem);//递归,自己调用自己
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值