求一个数据源为datatable从而构建一个树状结构的算法

夏天的枫 2016-09-06 10:49:36
如题所示,datatable中有两列(id,pid),如果有条数据的id等于另一条数据的pid,那么他俩就有父子关系了。数据大概两百条,有多少层未知,现有个类

public class Text
{
public Text Parent{get;set;}
public List<Text> Children{get;set;}
public Text()
{
this. Children=new List<Text>();
}
}

希望是存放在一个List<Text>里面
现在我用递归,发觉复杂度有点高。。。
...全文
193 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
夏天的枫 2016-09-06
  • 打赏
  • 举报
回复
引用 1 楼 zhi_ai_yaya 的回复:
ztree的simple data模式,或者.net的treeview
是要一个算法。。。
我叫小菜菜 2016-09-06
  • 打赏
  • 举报
回复
ztree的simple data模式,或者.net的treeview
夏天的枫 2016-09-06
  • 打赏
  • 举报
回复
引用 7 楼 xuzuning 的回复:
那是你没有理解这个结果的含义 他展示的是原始集合中每个节点的子节点的分布 而你需要的树状结构只是其中 pid 等于 0 的成员
受教了!!!!!
xuzuning 2016-09-06
  • 打赏
  • 举报
回复
那是你没有理解这个结果的含义 他展示的是原始集合中每个节点的子节点的分布 而你需要的树状结构只是其中 pid 等于 0 的成员
夏天的枫 2016-09-06
  • 打赏
  • 举报
回复
引用 3 楼 zhi_ai_yaya 的回复:
[quote=引用 2 楼 hjq624779687 的回复:] [quote=引用 1 楼 zhi_ai_yaya 的回复:] ztree的simple data模式,或者.net的treeview
是要一个算法。。。[/quote] 哪里高了。加载某个节点的子节点,只是一次扫描而已O(n) n为list的size。加载完毕也就是O(n*n) 如果每次扫描之后把节点从list中移除,那扫描的次数更少。 你要的是还原树目录结构,从树根逐层扫描就行了。或者把list传给控件自动实现。[/quote] 现在的问题就是在楼上了。
夏天的枫 2016-09-06
  • 打赏
  • 举报
回复
引用 4 楼 xuzuning 的回复:
        static void Main(string[] args)
        {
            //构造一个 DataTable
            var dt = new DataTable();
            dt.Columns.Add(new DataColumn("id", typeof(int)));
            dt.Columns.Add(new DataColumn("pid", typeof(int)));
            dt.Rows.Add(1, 0);
            dt.Rows.Add(2, 0);
            dt.Rows.Add(3, 1);
            dt.Rows.Add(4, 2);
            dt.Rows.Add(5, 3);

            //从 DataTable 生成 List<Text>
            var res = (from x in dt.AsEnumerable() select new Text((int)x["id"], (int)x["pid"])).ToList();
            //匹配父子关系
            foreach (var x in res) x.Children = res.FindAll(n => n.Pid == x.Id);
            //打印一下
            foreach (var x in res) see(x);

            Console.ReadKey();
        }
        //生成不需要递归,访问却是要递归的
        static void see(Text a, int n=0)
        {
            Console.WriteLine("{0,"+n+"}id:{1} pid:{2}", "", a.Id, a.Pid);
            foreach (var x in a.Children) see(x, n + 4);
        }
        public class Text
        {
            public Text Parent { get; set; }
            public List<Text> Children { get; set; }
            public int Id = 0;
            public int Pid = 0;
            public Text(int id, int pid)
            {
                Id = id;
                Pid = pid;
                this.Children = new List<Text>();
            }
        }
那么出了问题和我的一样了,{4,2}出现了两次!他其实是{2,0}的子集
xuzuning 2016-09-06
  • 打赏
  • 举报
回复
        static void Main(string[] args)
{
//构造一个 DataTable
var dt = new DataTable();
dt.Columns.Add(new DataColumn("id", typeof(int)));
dt.Columns.Add(new DataColumn("pid", typeof(int)));
dt.Rows.Add(1, 0);
dt.Rows.Add(2, 0);
dt.Rows.Add(3, 1);
dt.Rows.Add(4, 2);
dt.Rows.Add(5, 3);

//从 DataTable 生成 List<Text>
var res = (from x in dt.AsEnumerable() select new Text((int)x["id"], (int)x["pid"])).ToList();
//匹配父子关系
foreach (var x in res) x.Children = res.FindAll(n => n.Pid == x.Id);
//打印一下
foreach (var x in res) see(x);

Console.ReadKey();
}
//生成不需要递归,访问却是要递归的
static void see(Text a, int n=0)
{
Console.WriteLine("{0,"+n+"}id:{1} pid:{2}", "", a.Id, a.Pid);
foreach (var x in a.Children) see(x, n + 4);
}
public class Text
{
public Text Parent { get; set; }
public List<Text> Children { get; set; }
public int Id = 0;
public int Pid = 0;
public Text(int id, int pid)
{
Id = id;
Pid = pid;
this.Children = new List<Text>();
}
}
我叫小菜菜 2016-09-06
  • 打赏
  • 举报
回复
引用 2 楼 hjq624779687 的回复:
[quote=引用 1 楼 zhi_ai_yaya 的回复:] ztree的simple data模式,或者.net的treeview
是要一个算法。。。[/quote] 哪里高了。加载某个节点的子节点,只是一次扫描而已O(n) n为list的size。加载完毕也就是O(n*n) 如果每次扫描之后把节点从list中移除,那扫描的次数更少。 你要的是还原树目录结构,从树根逐层扫描就行了。或者把list传给控件自动实现。

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧