一、目的
该程序展示了如何将树形结构的数据(例如家庭成员信息)转化为一维列表形式,以便于存储、展示或操作。
二、流程思路
- 创建树 :首先通过
GetDemoTree
创建一个简单的家庭树,树的根节点是"爸爸",然后通过父子关系组织出完整的树结构。 - 递归转换 :通过
GetListTree
方法,将该树结构转化为一维列表。在这个过程中,树的每个节点都会被递归遍历,并转换为TreeList<PersonTree>
形式的条目,保存节点的层级信息(Level
)和节点的详细数据(Data
)。 - 结果 :最终生成的
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;
}