none
树结构的菜单,如何用递归函数读取 RRS feed

  • 问题

  • Name	LayerCode
    A1	1
    A2	1009
    A3	1009009
    A4	1009005
    A5	1009018
    A6	1009004
    A7	1009006
    A8	1009011
    A9	1009008
    A10	1009013
    A11	1009019
    A12	1009001
    A13	1009001001
    A14	1009001002
    A15	1009010
    A16	1009015
    A17	1009022
    A18	1009014
    A19	1009025
    A20	1009007
    A21	1009017
    A22	1009003
    A23	1009023
    A24	1009023001
    A25	1009024
    A26	1009012
    A27	1009020
    A28	1009016
    A29	1009002
    A30	1009002005
    A31	1009002004
    A32	1009002002
    A33	1009002003
    A34	1009002001
    A35	1009002006
    A36	1009021
    A37	1004
    A38	1004005
    A39	1004007
    A40	1004003
    A41	1004003013

    我一个多级菜单数据表, 如何根据 LayerCode 等级来读取到树对象里.

     3     public class  TreeNode<T>
     4     {
     5 
     6         public T Data { get; set; }
     7         public TreeNode<T> Parent { get; set; }
     8         public List<TreeNode<T>> Children { get; set; }
     9     }

    谢谢!

    2020年12月28日 15:37

答案

  • Hi GuanEr,

    根据你的描述,你想根据上面的菜单数据表读取到树对象中去。

    首先,我们需要创建一个树类,并且定义相关方法来删除或者添加节点。

        public class BoTree<T>
        {
            public BoTree()
            {
                nodes = new List<BoTree<T>>();
            }
    
            public BoTree(T data)
            {
                this.Data = data;
                nodes = new List<BoTree<T>>();
            }
    
            private BoTree<T> parent;
            /// <summary>
            /// 父结点
            /// </summary>
            public BoTree<T> Parent
            {
                get { return parent; }
            }
            /// <summary>
            /// 结点数据
            /// </summary>
            public T Data { get; set; }
    
            private List<BoTree<T>> nodes;
            /// <summary>
            /// 子结点
            /// </summary>
            public List<BoTree<T>> Nodes
            {
                get { return nodes; }
            }
            /// <summary>
            /// 添加结点
            /// </summary>
            /// <param name="node">结点</param>
            public void AddNode(BoTree<T> node)
            {
                if (!nodes.Contains(node))
                {
                    node.parent = this;
                    nodes.Add(node);
                    AddNode(node);
                    
                }
            }
            /// <summary>
            /// 添加结点
            /// </summary>
            /// <param name="nodes">结点集合</param>
            public void AddNode(List<BoTree<T>> nodes)
            {
                foreach (var node in nodes)
                {
                    if (!nodes.Contains(node))
                    {
                        node.parent = this;
                        nodes.Add(node);
                    }
                }
            }
            /// <summary>
            /// 移除结点
            /// </summary>
            /// <param name="node"></param>
            public void Remove(BoTree<T> node)
            {
                if (nodes.Contains(node))
                    nodes.Remove(node);
            }
            /// <summary>
            /// 清空结点集合
            /// </summary>
            public void RemoveAll()
            {
                nodes.Clear();
            }
        }

    其次,我们需要为我们的name和code创建一个类,这里我命名为了Student。

     public class Student
          {
            public string Name { get; set; }
    
            public string Code { get; set; }
          }

    最后,我们可以通过code的长度大小以及他是否以他的父节点名称为开始来添加节点。

      static List<Student> list = new List<Student>();
            static void Main(string[] args)
            {
    
                var lines = File.ReadAllLines("E:\\test.txt");
                foreach (var item in lines)
                {
                    string []arr = item.Split('\t');
                    list.Add(new Student { Name = arr[0], Code = arr[1] });
                }
                BoTree<Student> tree1 = new BoTree<Student>();
                tree1.Data = list[0];
                BoTree<Student> newtree1 = new BoTree<Student>();
                BoTree<Student> newtree2 = new BoTree<Student>();
                BoTree<Student> newtree3 = new BoTree<Student>();
                foreach (var item in list)
                {
                    if(item.Code.Length==4)
                    {
                        newtree1 = new BoTree<Student>();
                        newtree1.Data = item;
                        tree1.AddNode(newtree1);
                       
                    }
                    if (item.Code.Trim().Length == 7 && item.Code.StartsWith(newtree1.Data.Code))
                    {
                        newtree2 = new BoTree<Student>();
                        newtree2.Data = item;
                        newtree1.AddNode(newtree2);
                    }
                    if (item.Code.Trim().Length == 10 && item.Code.StartsWith(newtree2.Data.Code))
                    {
                        newtree3 = new BoTree<Student>();
                        newtree3.Data = item;
                        newtree2.AddNode(newtree3);
                    }
    
    
                    
                }
                Recursive(tree1);
                Console.ReadKey();
    
            }
            public static void Recursive(BoTree<Student> tree)
            {
                Console.WriteLine("name:{0},code:{1}", tree.Data.Name,tree.Data.Code);
                if (tree.Nodes.Count > 0)
                {
                    foreach (var item in tree.Nodes)
                    {
                        Recursive(item);
                    }
                }
            }

    另外说下,Recursive方法是用来遍历节点的,是用来检查的。

    测试的结果:

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 GuanEr 2020年12月29日 11:55
    2020年12月29日 8:44
    版主

全部回复

  • Hi GuanEr,

    根据你的描述,你想根据上面的菜单数据表读取到树对象中去。

    首先,我们需要创建一个树类,并且定义相关方法来删除或者添加节点。

        public class BoTree<T>
        {
            public BoTree()
            {
                nodes = new List<BoTree<T>>();
            }
    
            public BoTree(T data)
            {
                this.Data = data;
                nodes = new List<BoTree<T>>();
            }
    
            private BoTree<T> parent;
            /// <summary>
            /// 父结点
            /// </summary>
            public BoTree<T> Parent
            {
                get { return parent; }
            }
            /// <summary>
            /// 结点数据
            /// </summary>
            public T Data { get; set; }
    
            private List<BoTree<T>> nodes;
            /// <summary>
            /// 子结点
            /// </summary>
            public List<BoTree<T>> Nodes
            {
                get { return nodes; }
            }
            /// <summary>
            /// 添加结点
            /// </summary>
            /// <param name="node">结点</param>
            public void AddNode(BoTree<T> node)
            {
                if (!nodes.Contains(node))
                {
                    node.parent = this;
                    nodes.Add(node);
                    AddNode(node);
                    
                }
            }
            /// <summary>
            /// 添加结点
            /// </summary>
            /// <param name="nodes">结点集合</param>
            public void AddNode(List<BoTree<T>> nodes)
            {
                foreach (var node in nodes)
                {
                    if (!nodes.Contains(node))
                    {
                        node.parent = this;
                        nodes.Add(node);
                    }
                }
            }
            /// <summary>
            /// 移除结点
            /// </summary>
            /// <param name="node"></param>
            public void Remove(BoTree<T> node)
            {
                if (nodes.Contains(node))
                    nodes.Remove(node);
            }
            /// <summary>
            /// 清空结点集合
            /// </summary>
            public void RemoveAll()
            {
                nodes.Clear();
            }
        }

    其次,我们需要为我们的name和code创建一个类,这里我命名为了Student。

     public class Student
          {
            public string Name { get; set; }
    
            public string Code { get; set; }
          }

    最后,我们可以通过code的长度大小以及他是否以他的父节点名称为开始来添加节点。

      static List<Student> list = new List<Student>();
            static void Main(string[] args)
            {
    
                var lines = File.ReadAllLines("E:\\test.txt");
                foreach (var item in lines)
                {
                    string []arr = item.Split('\t');
                    list.Add(new Student { Name = arr[0], Code = arr[1] });
                }
                BoTree<Student> tree1 = new BoTree<Student>();
                tree1.Data = list[0];
                BoTree<Student> newtree1 = new BoTree<Student>();
                BoTree<Student> newtree2 = new BoTree<Student>();
                BoTree<Student> newtree3 = new BoTree<Student>();
                foreach (var item in list)
                {
                    if(item.Code.Length==4)
                    {
                        newtree1 = new BoTree<Student>();
                        newtree1.Data = item;
                        tree1.AddNode(newtree1);
                       
                    }
                    if (item.Code.Trim().Length == 7 && item.Code.StartsWith(newtree1.Data.Code))
                    {
                        newtree2 = new BoTree<Student>();
                        newtree2.Data = item;
                        newtree1.AddNode(newtree2);
                    }
                    if (item.Code.Trim().Length == 10 && item.Code.StartsWith(newtree2.Data.Code))
                    {
                        newtree3 = new BoTree<Student>();
                        newtree3.Data = item;
                        newtree2.AddNode(newtree3);
                    }
    
    
                    
                }
                Recursive(tree1);
                Console.ReadKey();
    
            }
            public static void Recursive(BoTree<Student> tree)
            {
                Console.WriteLine("name:{0},code:{1}", tree.Data.Name,tree.Data.Code);
                if (tree.Nodes.Count > 0)
                {
                    foreach (var item in tree.Nodes)
                    {
                        Recursive(item);
                    }
                }
            }

    另外说下,Recursive方法是用来遍历节点的,是用来检查的。

    测试的结果:

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 GuanEr 2020年12月29日 11:55
    2020年12月29日 8:44
    版主
  • 3Q 大神.
    2020年12月29日 11:55