C#高级:递归4-根据一颗树递归生成数据列表

一、目的

该程序展示了如何将树形结构的数据(例如家庭成员信息)转化为一维列表形式,以便于存储、展示或操作。

二、流程思路

  1. 创建树 :首先通过 GetDemoTree 创建一个简单的家庭树,树的根节点是"爸爸",然后通过父子关系组织出完整的树结构。
  2. 递归转换 :通过 GetListTree 方法,将该树结构转化为一维列表。在这个过程中,树的每个节点都会被递归遍历,并转换为 TreeList<PersonTree> 形式的条目,保存节点的层级信息(Level)和节点的详细数据(Data)。
  3. 结果 :最终生成的 listTree 是一个平坦的、按层级排列的列表,可以用于展示、处理或者进一步的分析。

三、代码展示

cs 复制代码
using System;
using System.Collections.Generic;

class PersonTree
{
    public int Id { get; set; }
    public int? ParentID { get; set; }
    public string Name { get; set; }

    public List<PersonTree> Children = new List<PersonTree>();
}

class TreeList<T> where T : class, new()
{
    /// <summary>
    /// 树ID(从T获取)
    /// </summary>
    public string Id { get; set; }
    /// <summary>
    /// 树的父级的ID(从T获取)
    /// </summary>
    public string PId { get; set; }
    /// <summary>
    /// 树的层级(从1开始)
    /// </summary>
    public int Level { get; set; }
    /// <summary>
    /// 树的对应节点的实体(如果数据量太大了,可以不写这个属性,把需要的属性例如Name放到外面去)
    /// </summary>
    public T Data { get; set; } = new T();
}

class Program
{
    static void Main()
    {
        //获取测试树:爸爸 - 我 妹妹 - 儿子 女儿
        var demoTree = GetDemoTree();

        //把树递归后转化为一维列表
        List<TreeList<PersonTree>> listTree = GetListTree(demoTree);
        ;
    }

    private static List<TreeList<PersonTree>> GetListTree(PersonTree demoTree, int level = 1)
    {
        List<TreeList<PersonTree>> output = new List<TreeList<PersonTree>>();

        // 每次递归都会new出output,因此不会反复添加根节点
        output.Add(new TreeList<PersonTree>
        {
            Id = demoTree.Id.ToString(),
            PId = demoTree.ParentID.ToString(),
            Level = level,
            Data = demoTree
        });

        // 如果有子节点,递归调用,增加层级
        if (demoTree.Children != null)
        {
            foreach (var item in demoTree.Children)
            {
                output.AddRange(GetListTree(item, level + 1));  // 递归调用时传递新的层级
            }
        }

        return output;
    }


    public static PersonTree GetDemoTree()
    {
        // 创建爸爸节点
        PersonTree dad = new PersonTree
        {
            Id = 1,
            Name = "爸爸",
            ParentID = null
        };

        // 创建我节点
        PersonTree me = new PersonTree
        {
            Id = 2,
            Name = "我",
            ParentID = dad.Id
        };

        // 创建妹妹节点
        PersonTree sister = new PersonTree
        {
            Id = 3,
            Name = "妹妹",
            ParentID = dad.Id
        };

        // 创建儿子节点
        PersonTree son = new PersonTree
        {
            Id = 4,
            Name = "儿子",
            ParentID = me.Id
        };

        // 创建女儿节点
        PersonTree daughter = new PersonTree
        {
            Id = 5,
            Name = "女儿",
            ParentID = me.Id
        };

        // 将儿子和女儿添加为我的子节点
        me.Children.Add(son);
        me.Children.Add(daughter);

        // 将我和妹妹添加为爸爸的子节点
        dad.Children.Add(me);
        dad.Children.Add(sister);
        return dad;
    }
}

【思考】假如PersonTree 没有 ParentID 这个字段 应该如何递归生成一维列表呢

【答案】递归方法多加一个Parent字段

cs 复制代码
private static List<TreeList<PersonTree>> GetListTree(PersonTree demoTree, int level = 1, string parentId = null)
{
    List<TreeList<PersonTree>> output = new List<TreeList<PersonTree>>();

    // 每次递归都会new出output,因此不会反复添加根节点
    output.Add(new TreeList<PersonTree>
    {
        Id = demoTree.Id.ToString(),
        PId = parentId,
        Level = level,
        Data = demoTree
    });

    // 如果有子节点,递归调用,增加层级
    if (demoTree.Children != null)
    {
        foreach (var item in demoTree.Children)
        {
            output.AddRange(GetListTree(item, level + 1, demoTree.Id.ToString()));  // 递归调用时传递新的父ID
        }
    }

    return output;
}
相关推荐
li星野27 分钟前
windows USB 了解
windows·stm32·单片机
夜晓码农1 小时前
Windows .gitignore文件不生效的情况排查
windows·git
code bean2 小时前
【C#】关键字 volatile
开发语言·c#
若汝棋茗2 小时前
C# 异步方法设计指南:何时使用 await 还是直接返回 Task?
开发语言·c#
快来卷java2 小时前
优化MyBatis-Plus批量插入策略
java·windows·spring·tomcat·maven·mybatis
lakernote2 小时前
Windows下在IntelliJ IDEA 使用 Git 拉取、提交脚本出现换行符问题
windows·git·intellij-idea
lljss20203 小时前
C# exe窗体项目改dll并调用
c#
office大师姐3 小时前
迈向云数据领域的第一步:Microsoft Azure DP-900认证指南
大数据·windows·microsoft·微软·azure
小张-森林人5 小时前
C#Lambda表达式与委托关系
c#
小张-森林人6 小时前
C#中,什么是委托,什么是事件及它们之间的关系
开发语言·c#