从字典构建树数据

时间:2013-11-20 04:41:38

标签: c# list dictionary tree

我的结构如下

{
   "Start": "CDG",
   "AirportsRoutes": 
{
    "BKK" : ["SIN", "DXB", "CDG", "SFO"],
    "CDG" : ["LHR", "SIN"],
    "JFK" : ["CDG", "DXB"],
    "JNB" : ["SIN"],
    "SIN" : ["SFO", "BKK"],
    "SFO" : ["JFK", "BKK", "LHR"],
    "LHR" : ["CDG", "JFK", "DXB"],
    "YYZ" : ["SFO", "JFK"],
    "DXB" : ["JNB", "SIN", "BKK"]
}
}

我为AirportsRoutes创建了Dictionary<string, List<string>>字典。

如果对根节点使用“CDG”,我想通过使用值作为下一个节点来构建此字典中的数据树。

如果找到与其父节点相同的密钥,则每个叶节点都将停止。

CDG->LHR->CDG
   ->LHR->JFK->CDG
   ->LHR->JFK->DXB->JNB->SIN->SFO->JFK
   ->LHR->JFK->DXB->JNB->SIN->SFO->BKK
   ->LHR->JFK->DXB->JNB->SIN->SFO->LHR
   ->LHR->JFK->DXB->JNB->SIN->BKK...
   ->LHR->JFK->DXB->SIN->SFO...
   ->LHR->JFK->DXB->SIN->BKK..
   ->LHR->JFK->DXB->BKK..
   ->LHR->DXB..

每个人都知道如何制作或者我需要将词典更改为其他内容吗?

1 个答案:

答案 0 :(得分:1)

这款小型控制台应用可以满足您的需求:

public class Program
{
    public class TreeNode<T>
    {
        public List<TreeNode<T>> children = new List<TreeNode<T>>();
        public T thisItem;
        public TreeNode<T> parent;
    }

    public static void Main(string[] args)
    {
        var dict = new Dictionary<string, List<string>>
        {
            {"BKK", new List<string>{"SIN", "DXB", "CDG", "SFO"}},
            {"CDG" , new List<string>{"LHR", "SIN"}},
            {"JFK" , new List<string>{"CDG", "DXB"}},
            {"JNB" , new List<string>{"SIN"}},
            {"SIN" , new List<string>{"SFO", "BKK"}},
            {"SFO" , new List<string>{"JFK", "BKK", "LHR"}},
            {"LHR" , new List<string>{"CDG", "JFK", "DXB"}},
            {"YYZ" , new List<string>{"SFO", "JFK"}},
            {"DXB", new List<string> {"JNB", "SIN", "BKK"}}
        };

        var tree = BuildTree(dict, "CDG");
    }

    public static TreeNode<T> BuildTree<T>(Dictionary<T, List<T>> dictionary, T root)
    {
        var newTree = new TreeNode<T>
        {
            thisItem = root,
        };

        newTree.children = GetChildNodes(dictionary, newTree);

        return newTree;
    }

    public static List<TreeNode<T>> GetChildNodes<T>(Dictionary<T, List<T>> dictionary, TreeNode<T> parent)
    {
        var nodeList = new List<TreeNode<T>>();

        if (dictionary.ContainsKey(parent.thisItem))
        {
            foreach (var item in dictionary[parent.thisItem])
            {
                var nodeToAdd = new TreeNode<T>
                {
                    thisItem = item,
                    parent = parent,
                };

                if (!ContainedInParent(parent, item))
                {
                    nodeToAdd.children = GetChildNodes(dictionary, nodeToAdd);
                }

                // output leaf node for debugging!
                if (nodeToAdd.children.Count == 0)
                {
                    Console.WriteLine(NodeString(nodeToAdd));
                }

                nodeList.Add(nodeToAdd);
            }
        }

        return nodeList;
    }

    private static string NodeString<T>(TreeNode<T> node)
    {
        return (node.parent != null ? NodeString(node.parent) + "->" : string.Empty) + node.thisItem;
    }

    private static bool ContainedInParent<T>(TreeNode<T> parent, T item)
    {
        var found = false;

        if (parent != null)
        {
            if (parent.thisItem.Equals(item))
            {
                found = true;
            }
            else
            {
                found = ContainedInParent(parent.parent, item);
            }
        }

        return found;
    }
}

输出结果为:

  

CDG-&GT; LHR-&GT; CDG

     

CDG-&GT; LHR-&GT; JFK-&GT; CDG

     

CDG-&GT; LHR-&GT; JFK-&GT; DXB-&GT; JNB-&GT; SIN-&GT; SFO-&GT; JFK

     

CDG-&GT; LHR-&GT; JFK-&GT; DXB-&GT; JNB-&GT; SIN-&GT; SFO-&GT; BKK-&GT; SIN

     

CDG-&GT; LHR-&GT; JFK-&GT; DXB-&GT; JNB-&GT; SIN-&GT; SFO-&GT; BKK-&GT; DXB

     

CDG-&GT; LHR-&GT; JFK-&GT; DXB-&GT; JNB-&GT; SIN-&GT; SFO-&GT; BKK-&GT; CDG

     

.........