C#构建树形结构数据(全部构建,查找构建)

yizhihongxing

C#构建树形结构数据(全部构建,查找构建)

前言

树形结构数据在实际开发中非常常见,具有分级、层级、分类等特点,通常应用于目录结构、组织机构、商品分类等场景。本文将介绍如何使用C#构建树形结构数据,包括全部构建和查找构建两种方案。

全部构建

步骤一:定义数据结构

我们假设有一个数据表,包含id、parentId、name三个字段,其中id为自增主键,parentId为父节点id,name为节点名称,例如:

id parentId name
1 0 根节点1
2 1 二级节点1
3 1 二级节点2
4 2 三级节点1
5 2 三级节点2

我们可以定义一个与之对应的数据结构,例如:

public class TreeNode
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<TreeNode> Children { get; set; }
}

其中,Id为节点id,Name为节点名称,Children为子节点集合。

步骤二:加载数据

我们需要将数据表中的数据加载到内存中,使用List存储。

List<TreeNode> nodes = new List<TreeNode>();
// 加载数据
foreach (DataRow row in dataTable.Rows)
{
    var node = new TreeNode
    {
        Id = row.Field<int>("id"),
        Name = row.Field<string>("name")
    };
    nodes.Add(node);
}

步骤三:构建树形结构

接下来的任务就是将这个扁平的节点列表转换成树形结构。我们可以采用递归的方式进行构建:

public static List<TreeNode> BuildTree(List<TreeNode> nodes, int parentId = 0)
{
    var tree = new List<TreeNode>();
    foreach (var node in nodes.Where(n => n.ParentId == parentId))
    {
        node.Children = BuildTree(nodes, node.Id);
        tree.Add(node);
    }
    return tree;
}

当parentId为0时,意味着构建根节点。对于每一个节点,我们在nodes中查找其子节点,并添加到Children中。

步骤四:完整代码

public class TreeNode
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public List<TreeNode> Children { get; set; }
}

public static class TreeBuilder
{
    public static List<TreeNode> BuildTree(List<TreeNode> nodes, int parentId = 0)
    {
        var tree = new List<TreeNode>();
        foreach (var node in nodes.Where(n => n.ParentId == parentId))
        {
            node.Children = BuildTree(nodes, node.Id);
            tree.Add(node);
        }
        return tree;
    }
}

查找构建

如果数据量较大,全部构建可能会导致性能问题。在这种情况下,我们可以使用查找构建的方式,只构建需要的节点。

步骤一:定义数据结构

与全部构建相同,我们需要定义一个树形结构的节点类:

public class TreeNode
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<TreeNode> Children { get; set; }
}

步骤二:加载数据

同样是将数据表中的数据加载到内存中,使用List存储。

List<TreeNode> nodes = new List<TreeNode>();
// 加载数据
foreach (DataRow row in dataTable.Rows)
{
    var node = new TreeNode
    {
        Id = row.Field<int>("id"),
        Name = row.Field<string>("name")
    };
    nodes.Add(node);
}

步骤三:查找构建

我们通过递归的方式,构建指定节点的树形结构。具体实现如下:

public static List<TreeNode> BuildTree(List<TreeNode> nodes, int id)
{
    var tree = new List<TreeNode>();
    foreach (var node in nodes.Where(n => n.ParentId == id))
    {
        node.Children = BuildTree(nodes, node.Id);
        tree.Add(node);
    }
    return tree;
}

步骤四:完整代码

public class TreeNode
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public List<TreeNode> Children { get; set; }
}

public static class TreeBuilder
{
    public static List<TreeNode> BuildTree(List<TreeNode> nodes, int parentId = 0)
    {
        var tree = new List<TreeNode>();
        foreach (var node in nodes.Where(n => n.ParentId == parentId))
        {
            node.Children = BuildTree(nodes, node.Id);
            tree.Add(node);
        }
        return tree;
    }

    public static List<TreeNode> BuildSubTree(List<TreeNode> nodes, int id)
    {
        var tree = new List<TreeNode>();
        foreach (var node in nodes.Where(n => n.Id == id))
        {
            node.Children = BuildTree(nodes, node.Id);
            tree.Add(node);
        }
        return tree;
    }
}

示例说明

我们假设有一张商品分类表,其中的数据如下:

id parentId name
1 0 电器类
2 1 彩电类
3 1 冰箱类
4 2 液晶电视
5 2 智能电视
6 3 单门冰箱
7 3 双门冰箱

示例一:全部构建

我们可以使用以下代码构建整个树形结构:

List<TreeNode> nodes = LoadDataFromDb();
List<TreeNode> tree = TreeBuilder.BuildTree(nodes);

构建出的树形结构如下:

电器类
|--彩电类
|  |--液晶电视
|  |--智能电视
|--冰箱类
   |--单门冰箱
   |--双门冰箱

示例二:查找构建

如果我们只需要构建彩电类及其子类别的树形结构,我们可以使用以下代码:

List<TreeNode> nodes = LoadDataFromDb();
List<TreeNode> tree = TreeBuilder.BuildSubTree(nodes, 2);

构建出的树形结构如下:

彩电类
|--液晶电视
|--智能电视

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#构建树形结构数据(全部构建,查找构建) - Python技术站

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • .NET Core中的HttpClientFactory类用法详解

    HttpClientFactory是.NET Core中的一个新特性,它提供了一种更好的方式来管理和使用HttpClient实例。在本攻略中,我们将详细讲解HttpClientFactory的用法,并提供两个示例来说明它的使用。 什么是HttpClientFactory? HttpClientFactory是.NET Core 2.1中引入的一个新特性,它提…

    C# 2023年5月16日
    00
  • c#斐波那契数列(Fibonacci)(递归,非递归)实现代码

    C#中可以使用递归和非递归两种方式实现斐波那契数列。 一、递归实现代码 递归实现斐波那契数列比较简单,代码如下: public static int Fibonacci_Recursive(int n) { if (n <= 0) { return 0; } if (n == 1 || n == 2) { return 1; } return Fibo…

    C# 2023年5月31日
    00
  • 关于C#结构体 你需要知道的

    关于C#结构体 你需要知道的 在C#中,结构体是一种轻量级的数据类型,它是一种值类型,而不是引用类型。结构体可以包含字段、方法、属性、构造函数和操作符等成员。 为什么要使用结构体 使用结构体可以提高程序的性能和效率。因为结构体是值类型,而值类型是直接存储在栈上的,这样就避免了装箱和拆箱带来的性能损失。另外,结构体通常不需要被垃圾回收机制处理,所以也减少了内存…

    C# 2023年5月31日
    00
  • 详解.NET中string与StringBuilder在字符串拼接功能上的比较

    接下来我将详细讲解”.NET中string与StringBuilder在字符串拼接功能上的比较”。 什么是string和StringBuilder? string是C#中一种常见的字符串类型,它是不可变的,一旦被创建,就不能被修改。 StringBuilder是C#中的另一种字符串类型,它是可变的,可以进行直接修改。 字符串拼接 在实际的应用中,我们经常需要…

    C# 2023年6月8日
    00
  • 详解C# 利用反射根据类名创建类的实例对象

    详解C# 利用反射根据类名创建类的实例对象 在C#中,反射是一个重要的特性,可以让我们在运行时动态地加载和分析程序集。利用反射可以实现在运行时根据类名创建对象的目的。本篇文章将详细讲解利用反射根据类名创建类的实例对象的完整攻略。 步骤一:获取类型信息 使用反射创建实例对象的第一步是获取类型信息。在C#中,Type类表示一个类型的元数据。我们可以使用Type.…

    C# 2023年6月1日
    00
  • asp.net Split分割字符串的方法

    当使用ASP.NET进行开发时,分割字符串是一项非常常见的任务。ASP.NET中的Split()方法是一种简单有效的将字符串分成单独纯文本段的方法。 Split()方法的基本用法 Split()方法可以用于按照指定的分隔符将一个字符串分割成多个子串。其基本用法如下所示: string str = "apple, banana, cherry, da…

    C# 2023年6月3日
    00
  • 浅谈对c# 面向对象的理解

    浅谈对C#面向对象的理解 C# 面向对象编程的基本概念 C# 是一种面向对象的编程语言,对象是构成类的基本单元,一个类包含属性、方法和事件。在面向对象编程中,将程序中的所有事物都看作对象,这些对象之间可以互相传递消息,完成整个程序的任务。一般来说,面向对象编程强调以下概念: 类(Class):类是面向对象程序的基本单元,类定义了一组数据和行为,用于描述某个实…

    C# 2023年6月1日
    00
  • asp.net 细说文件读写操作(读写锁)

    ASP.NET细说文件读写操作(读写锁) 介绍 在ASP.NET应用程序中,文件读写操作是很常见的场景,但是如果多个线程同时访问同一个文件并执行读写操作,就有可能会引起线程安全问题,进而导致应用程序崩溃或数据丢失等问题。为了确保线程安全,我们需要采用读写锁来控制文件的访问。本文将详细讲解ASP.NET应用程序中如何实现文件读写操作,并介绍读写锁的使用。 文件…

    C# 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部