在Go中将地图转换为树

时间:2017-07-25 23:01:26

标签: algorithm go data-structures tree

我有一个非常具体的问题,我无法找到解决方案。

我有一个map[string]Metric,我希望将其转换为树,以便在前端使用。 Metric接口看起来有一个Path()和一个Name()方法,name方法返回一个以句点分隔的路径的最后一部分(所以路径为' my.awesome。指标'表示此指标的名称为' metric') 树应按路径排序,并应包含IndexNode s。这个结构如下所示:

type IndexNode struct {
    Name string
    Path string
    Children []*IndexNode
}

所以这样的地图:

{
    my.awesome.metric.downloads
    my.awesome.othermetric.downloads
    my.awesome.othermetric.uploads
    my.other.cool.metric
}

应该导致这样的树:(抱歉粗糙的ascii艺术)

     +-- other -- cool -- metric
     |
my --+             +-- metric -- downloads
     |             |
     +-- awesome --+                 +-- downloads
                   |                 |
                   +-- othermetric --+
                                     |
                                     +-- uploads

请注意,我只有一个根节点(在本例中为my)。树内的顺序对我来说无关紧要。

我尽我所能,无法弄明白...经过大量的googleing(只向我展示了如何创建二元搜索树和GoDS库),我辞职并决定在这里问我的第一个问题

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

Children更改为map[string]*IndexNode,您就在那里。如果你不介意看起来很慢,你可以使用切片,但这意味着你需要搜索切片,以便在每次遍历树时找到你想要的孩子。在这种情况下,地图更快更容易。

现在你只需要编写一个递归函数来逐步降低树,根据需要为路径中的每个元素创建节点,直到它到达终点。

不幸的是,我没有准备好访问我的另一台计算机上的所有代码示例:(

一个快速而又肮脏的例子:

type Tree struct {
    Parent *Tree
    Children map[string]*Tree
    Payload bool // Your data here
}

func NewTree(parent *Tree, path []string, payload bool) *Tree {
    if parent == nil {
        parent = &Tree{nil, map[string]*Tree{}, false}
    }
    if len(path) == 0 {
        parent.Payload = payload
        return parent
    }

    child := parent.Children[path[0]]
    if child == nil {
        child = &Tree{parent, map[string]*Tree{}, false}
        parent.Children[path[0]] = child
    }
    return NewTree(child, path[1:], payload)
}

用法:

root := NewTree(nil, nil, false)
newnode := NewTree(root, []string{"A", "B", "C"}, true)

Try it on the Go Playground!

答案 1 :(得分:0)

这是使用地图的解决方案,遍历它可以帮助您填充数据结构。可以在树导航https://play.golang.org/p/sVqBCVgiBG

中创建“Parent xxx Child xxx”的节点