c# 递归

本文介绍了一种使用C#实现的列表到树形结构的转换方法,并提供了递归获取选中节点及其父节点的树形结构的示例。通过具体的代码实现了基于城市列表构建树形结构的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1)递归将列表转化成树

2)递归获取选中节点树

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp10
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 获取城市列表
            List<City> list = GetList();
            Console.WriteLine("城市集合");
            Console.WriteLine(JsonConvert.SerializeObject(list));
            #endregion

            #region 根据城市列表,递归获取城市树
            List<TreeNode> tree = GetTree(list);
            Console.WriteLine("城市树结构");
            Console.WriteLine(JsonConvert.SerializeObject(tree));
            #endregion


            #region 获取选中节点树(包括父节点)
            Console.WriteLine("选中城市(杭州、嘉善、吴江)");
            List<int> ids = new List<int> { 11, 121, 211 };
            List<TreeNode> newTree = GetSelectedTree(tree, ids);
            Console.WriteLine("选中城市树结构");
            Console.WriteLine(JsonConvert.SerializeObject(newTree));
            #endregion
        }
        /// <summary>
        /// 获取城市列表
        /// </summary>
        /// <returns></returns>
        static List<City> GetList()
        {
            List<City> list = new List<City>();
            list.Add(new City { id = 1, name = "浙江", upperid = null });
            list.Add(new City { id = 2, name = "江苏", upperid = null });
            list.Add(new City { id = 3, name = "福建", upperid = null });
            list.Add(new City { id = 11, name = "杭州", upperid = 1 });
            list.Add(new City { id = 12, name = "嘉兴", upperid = 1 });
            list.Add(new City { id = 21, name = "苏州", upperid = 2 });
            list.Add(new City { id = 22, name = "无锡", upperid = 2 });
            list.Add(new City { id = 31, name = "福州", upperid = 3 });
            list.Add(new City { id = 32, name = "厦门", upperid = 3 });
            list.Add(new City { id = 111, name = "萧山", upperid = 11 });
            list.Add(new City { id = 112, name = "临安", upperid = 11 });
            list.Add(new City { id = 121, name = "嘉善", upperid = 12 });
            list.Add(new City { id = 122, name = "桐乡", upperid = 12 });
            list.Add(new City { id = 211, name = "吴江", upperid = 21 });
            list.Add(new City { id = 212, name = "常熟", upperid = 21 });
            return list;
        }

        /// <summary>
        /// 根据城市列表,递归获取城市树
        /// </summary>
        /// <param name="list">城市列表</param>
        /// <returns>树状结构</returns>
        static List<TreeNode> GetTree(List<City> list)
        {
            List<TreeNode> tree = new List<TreeNode>();
            foreach (City item in list.Where(a => a.upperid == null))
            {
                TreeNode roorNode = new TreeNode();
                roorNode.id = item.id;
                roorNode.name = item.name;
                roorNode.upperid = item.upperid;
                roorNode.path.Add(roorNode.id);
                GetChildren(roorNode, list);
                tree.Add(roorNode);
            }

            static void GetChildren(TreeNode nodel, List<City> list)
            {
                var children = list.Where(a => a.upperid == nodel.id);
                if (children != null && children.Count() > 0)
                {
                    nodel.children = new List<TreeNode>();
                    foreach (City item in children)
                    {
                        TreeNode childNode = new TreeNode();
                        childNode.id = item.id;
                        childNode.name = item.name;
                        childNode.upperid = item.upperid;
                        childNode.path.AddRange(nodel.path);
                        childNode.path.Add(childNode.id);
                        GetChildren(childNode, list);
                        nodel.children.Add(childNode);
                    }
                }
            }

            return tree;
        }
        /// <summary>
        /// 获取选中节点树(包括父节点)
        /// </summary>
        /// <param name="tree">原树状结构</param>
        /// <param name="ids">选中节点</param>
        /// <returns>选中树状结构(包括父节点)</returns>
        static List<TreeNode> GetSelectedTree(List<TreeNode> tree, List<int> ids)
        {
            List<TreeNode> newTree = new List<TreeNode>();
            foreach (TreeNode rootNode in tree)
            {
                bool isKeep = IsNodeKeep(rootNode, ids);
                if (isKeep)
                    newTree.Add(rootNode);
            }

            static bool IsNodeKeep(TreeNode node, List<int> ids)
            {
                bool isKeep = false;
                //如果节点被选中,节点保留
                if (ids.Contains(node.id))
                    isKeep = true;
                //存在子节点,循环子节点
                if (node.children != null && node.children.Count > 0)
                {
                    //定义新子节点集合
                    List<TreeNode> newChildren = new List<TreeNode>();
                    foreach (TreeNode childNode in node.children)
                    {
                        //将需要保留的节点放入新子节点集合
                        bool isChildKeep = IsNodeKeep(childNode, ids);
                        if (isChildKeep)
                            newChildren.Add(childNode);
                    }
                    //新子节点集合存在数据,节点保留
                    if (newChildren.Count > 0)
                        isKeep = true;
                    node.children = newChildren;
                }
                return isKeep;
            }
            return newTree;
        }
    }
    /// <summary>
    /// 城市节点表
    /// </summary>
    public class TreeNode : City
    {
        public TreeNode()
        {
            path = new List<int>();
        }
        /// <summary>
        /// 全路径
        /// </summary>
        public List<int> path { get; set; }
        /// <summary>
        /// 儿子
        /// </summary>
        public List<TreeNode> children { get; set; }
    }
    /// <summary>
    /// 城市表
    /// </summary>
    public class City
    {
        /// <summary>
        /// 主键
        /// </summary>
        public int id { get; set; }
        /// <summary>
        /// 名称
        /// </summary>
        public string name { get; set; }
        /// <summary>
        /// 父主键
        /// </summary>
        public int? upperid { get; set; }
    }
}

全树json效果

[{
	"path": [1],
	"children": [{
		"path": [1, 11],
		"children": [{
			"path": [1, 11, 111],
			"children": null,
			"id": 111,
			"name": "萧山",
			"upperid": 11
		}, {
			"path": [1, 11, 112],
			"children": null,
			"id": 112,
			"name": "临安",
			"upperid": 11
		}],
		"id": 11,
		"name": "杭州",
		"upperid": 1
	}, {
		"path": [1, 12],
		"children": [{
			"path": [1, 12, 121],
			"children": null,
			"id": 121,
			"name": "嘉善",
			"upperid": 12
		}, {
			"path": [1, 12, 122],
			"children": null,
			"id": 122,
			"name": "桐乡",
			"upperid": 12
		}],
		"id": 12,
		"name": "嘉兴",
		"upperid": 1
	}],
	"id": 1,
	"name": "浙江",
	"upperid": null
}, {
	"path": [2],
	"children": [{
		"path": [2, 21],
		"children": [{
			"path": [2, 21, 211],
			"children": null,
			"id": 211,
			"name": "吴江",
			"upperid": 21
		}, {
			"path": [2, 21, 212],
			"children": null,
			"id": 212,
			"name": "常熟",
			"upperid": 21
		}],
		"id": 21,
		"name": "苏州",
		"upperid": 2
	}, {
		"path": [2, 22],
		"children": null,
		"id": 22,
		"name": "无锡",
		"upperid": 2
	}],
	"id": 2,
	"name": "江苏",
	"upperid": null
}, {
	"path": [3],
	"children": [{
		"path": [3, 31],
		"children": null,
		"id": 31,
		"name": "福州",
		"upperid": 3
	}, {
		"path": [3, 32],
		"children": null,
		"id": 32,
		"name": "厦门",
		"upperid": 3
	}],
	"id": 3,
	"name": "福建",
	"upperid": null
}]

获取选中节点树(包括父节点)

[{
	"path": [1],
	"children": [{
		"path": [1, 11],
		"children": [],
		"id": 11,
		"name": "杭州",
		"upperid": 1
	}, {
		"path": [1, 12],
		"children": [{
			"path": [1, 12, 121],
			"children": null,
			"id": 121,
			"name": "嘉善",
			"upperid": 12
		}],
		"id": 12,
		"name": "嘉兴",
		"upperid": 1
	}],
	"id": 1,
	"name": "浙江",
	"upperid": null
}, {
	"path": [2],
	"children": [{
		"path": [2, 21],
		"children": [{
			"path": [2, 21, 211],
			"children": null,
			"id": 211,
			"name": "吴江",
			"upperid": 21
		}],
		"id": 21,
		"name": "苏州",
		"upperid": 2
	}],
	"id": 2,
	"name": "江苏",
	"upperid": null
}]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值