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

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日

相关文章

  • C#中读取App.config配置文件代码实例

    下面就给您详细讲解一下在C#中读取App.config配置文件的完整攻略。 什么是App.config? 在C#项目中,App.config是存放配置信息的文件,经常用来保存应用程序的配置信息,比如数据库连接字符串、路径等等。在项目中对于一些数据的统一管理是非常有用的,修改方便,且使用配置文件时只需要修改App.config即可不用修改代码。 读取App.c…

    C# 2023年6月1日
    00
  • C#中数组、ArrayList和List三者的区别详解及实例

    下面是详细讲解 “C#中数组、ArrayList和List三者的区别详解及实例” 的完整攻略。 1. 数组 1.1 定义方式 数组是同一种数据类型的元素的集合,它的大小是固定的。 在 C# 中,我们可以通过以下方式定义和初始化一个数组: int[] arr1 = new int[5]; // 定义一个包含 5 个元素的 int 数组 int[] arr2 =…

    C# 2023年5月15日
    00
  • C#使用HttpWebRequest与HttpWebResponse模拟用户登录

    C#使用HttpWebRequest与HttpWebResponse模拟用户登录的完整攻略如下: 总览 本攻略将通过以下步骤完成模拟登陆: 构造登陆页面的请求,获取对应的Cookie。 通过获取到的Cookie构造真正的登陆请求,提交登陆信息。 发送登陆请求,获取登陆后的响应,做进一步的处理。 步骤一:构造登陆页面的请求 首先,我们需要发送一个请求来获取登陆…

    C# 2023年5月31日
    00
  • c# 连接池的设置与使用

    关于c#连接池的设置与使用,我会提供以下内容: 什么是连接池 连接池是一种技术,用于维护和管理连接的缓存,自动分配和回收数据库连接对象。当应用程序请求连接资源时,连接池会检查是否有可用的连接对象,如果有就直接返回给应用程序,没有则自动创建连接对象,并将其添加到连接池中。当应用程序不再使用连接对象时,连接池会将连接对象回收并重新放回池中供下次使用。 配置连接池…

    C# 2023年5月15日
    00
  • asp.net直接Response输出WML页面示例代码

    当我们需要在 ASP.NET 程序中输出 WML 页面时,可以使用 Response.Write 方法直接将 WML 页面代码输出到响应流中。以下是实现该功能的完整攻略: 第一步:设置响应内容类型 在 ASP.NET 程序中,我们需要设置响应内容类型,以便浏览器能够正确解析页面。对于 WML 页面,我们需要设置响应内容类型为 “text/vnd.wap.wm…

    C# 2023年5月31日
    00
  • 详解如何在C#中接受或拒绝Excel中的修订

    如何在C#中接受或拒绝Excel中的修订 为了接受或拒绝Excel文档中的修订,我们需要使用C#中的Microsoft.Office.Interop.Excel库。下面是实现此目的的步骤: 步骤1:在Visual Studio中创建C#项目,并添加对Microsoft.Office.Interop.Excel库的引用 步骤2:打开Excel文档 为了打开Ex…

    C# 2023年6月6日
    00
  • 在 C# 中使用 Span 和 Memory 编写高性能代码的详细步骤

    在 C# 中使用 Span<T> 和 Memory<T> 可以大幅提升代码性能,并且这两个类型被广泛地用于处理数组和内存操作。在本文中,我们将详细介绍如何使用Span<T> 和 Memory<T> 来编写高性能代码。 一、什么是 Span 和 Memory 首先,我们需要了解一下什么是 Span<T&gt…

    C# 2023年5月31日
    00
  • asp.net(C#) 生成随机验证码的代码

    生成随机验证码的代码可以使用C#语言的 .NET Framework提供的Random类和StringBuilder类。下面是示例代码: using System; using System.Text; public static class RandomCode { public static string Generate(int length) { c…

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