树结构中的输出列表

时间:2016-05-11 12:59:32

标签: c# .net recursion

我需要在C#中编写一个递归函数,它将在控制台中以下列树形结构打印数据:

-Continent
--Country
---Province
----City1
----- Suburb4
------ House3
----City2
----- Suburb1
----- Suburb2
------ House1
------ House6
----- Suburb3
------ House4
------ House5

我有一个数据集列表区域如下:

ID  Description ParentID
 1  Continent   Null
2   Country     1
3   Province    2
4   City1       3
5   Suburb1     6
6   City2       3
7   Suburb2     6
8   Suburb3     6
9   Suburb4     4
10  House1      7
11  House3      9
12  House4      8
13  House5      8
14  House6      7

如何让下面的代码创建输出?

我尝试过以下方法:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Press any key to start...");
            Console.ReadKey(true);

        var area = new List<Areas>();
        area = PopulateList(area);

        area.Sort((s1,s2) => s1.ParentID.CompareTo(s2.ParentID));

        PrintData(area);

        Console.WriteLine("Press any key to exit...");
        Console.ReadKey(true);

    }


    private static void PrintData(List<Areas> area)
    {
        Console.WriteLine("-" + area[0].Description);
        string[] array = new string[13];

        foreach (var item in area) 
        {
            string[] children = GetChildren(area, item);
            if (children != null)
            {
                int count = 0;
                foreach (var child in children)
                {
                    if (child != null)
                    {
                        for (int i = 0; i <= count +1; i++)
                        {
                            Console.Write("-");
                        }

                        int count2 = 0;
                        foreach (string x in array)
                        {
                            if ((x != null) && (x.Contains(children[count])))
                            {

                            }
                            else
                            {
                                if (children[count2] != null)
                                {
                                    Console.WriteLine(children[count2]);

                                    array[count2] = children[count2];
                                    count2++;
                                }
                            }
                        }
                        count++;

                    }
                }
            }
        }

    }

    private static string[] GetChildren(List<Areas> areas, Areas item)
    {
        string[] children = new string[13];
        int count = 0;
        foreach (var area in areas)
        {
            if ((item.ID == area.ParentID) && (area.ParentID != 0))
            {
                children[count] = area.Description;
                count++;

                foreach (var area2 in areas)
                {
                    if ((area.ID == area2.ParentID) && (area2.ParentID != 0))
                    {
                        children[count] = area2.Description;
                        //count++;
                        foreach (var area3 in areas)
                        {
                            if ((area.ID == area3.ParentID) && (area3.ParentID != 0))
                            {
                                children[count] = area3.Description;
                                //count++;
                            }
                        }
                    }
                }
            }

        }
        return children;
    }

我得到的输出是这样的:

-Continent
--Country
Province
---Country
Province
--Province
City2
---Province
...

2 个答案:

答案 0 :(得分:2)

以下是您想要的。我已将数据加载到通用列表中,但原理是相同的

    private List<Entity> _entities = new List<Entity>();


    private void Form1_Load(object sender, EventArgs e)
    {

        _entities.Add(new Entity(1, "Continent", null));
        _entities.Add(new Entity(2, "Country", 1));
        _entities.Add(new Entity(3, "Province", 2));
        _entities.Add(new Entity(4, "City1", 3));
        _entities.Add(new Entity(5, "Suburb1", 6));
        _entities.Add(new Entity(6, "City2", 3));
        _entities.Add(new Entity(7, "Suburb2", 6));
        _entities.Add(new Entity(8, "Suburb3", 6));
        _entities.Add(new Entity(9, "Suburb4", 4));
        _entities.Add(new Entity(10, "House1", 7));
        _entities.Add(new Entity(11, "House3", 9));
        _entities.Add(new Entity(12, "House4", 8));
        _entities.Add(new Entity(13, "House5", 8));
        _entities.Add(new Entity(14, "House6", 7));

        var parent = _entities.Find((x) => x.ParentId == 0);
        EnumerateChildren(parent, 1);
    }

    private void EnumerateChildren(Entity thisEntity, int level)
    {
        Debug.WriteLine(new string('-', level) + thisEntity.Name);
        foreach (var child in _entities.FindAll((x) => x.ParentId == thisEntity.Id).OrderBy(x => x.Id))
        {
            EnumerateChildren(child, level + 1);
        }
    }

    private class Entity
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int ParentId { get; set; }
        public Entity(int id, string name, int? parentId)
        {
            this.Id = id;
            this.ParentId = parentId.HasValue ? Convert.ToInt32(parentId) : 0;
            this.Name = name;
        }
    }

答案 1 :(得分:1)

我会在Dictionary<int, List<Area>>中加载区域信息,其中int键代表ParentIDList<Area>值代表给定ParentID的所有子区域}。

例如:

struct Area {
    public int ID;
    public string Description;
    public int? ParentID;
}

void OutputAreasTree() {
    IEnumerable<Area> areas = GetAreasFromDataSource();
    OutputAreasTreeFromNode(LoadAreasByParentID(areas), areasByParentID[0][0], 1);
}

Dictionary<int, List<Area>> LoadAreasByParentID(IEnumerable<Area> areas) {
    Dictionary<int, List<Area>> areasByParentID = new Dictionary<int, List<Area>>();
    foreach (Area area in areas) {
        int parentID = area.ParentID ?? 0; // use 0 as the ParentID of the root
        List<Area> children;
        if (!areasByParentID.TryGetValue(parentID, out children)) {
            children = new List<Area>();
            areasByParentID.Add(parentID, children);
        }
        children.Add(area);
    }
    return areasByParentID;
}

void OutputAreasTreeFromNode(Dictionary<int, List<Area>> areasByParentID, Area area, int depth) {
    for (int i = 0; i < depth; i++)
        Console.Write('-');
    Console.WriteLine(area.Description);
    List<Area> children;
    if (areasByParentID.TryGetValue(area.ID, out children)) {
        foreach (Area child in children)
            OutputAreasTreeFromNode(areasByParentID, child, depth+1);
    }
}

希望它有所帮助。