【问题标题】:Get a tree like structure out of path string从路径字符串中获取树状结构
【发布时间】:2017-05-05 13:09:37
【问题描述】:

我从 2 天开始就被困住了,因为我对指针和递归并不坚定。我有一个类似结构的路径数组,可以说:

s:=[]string {
  "a/b/c",
  "a/b/g",
  "a/d",
}

使用这样的数据结构:

 type Node struct {
   Name     string `json:"name"`
   Children []Node `json:"children"`
}

我想得到这样的结果:

{
 "name": "a",
 "children": [
     {
      "name": "b",
      "children": [
        {
         "name": "c",
         "children": []
        },
        {
         "name": "g",
         "children": []
        }
      ]
    },
    {
     "name": "d",
     "children": []
    }
  ]
}

我尝试使用递归构建它,它工作得很好,但只适用于一个字符串(例如“a/b/c”),只要我尝试实现应该添加缺失节点的东西(“g " in "a/b/g") 到我被卡住的树。

我有类似的东西:

func appendChild(root Node, children []string) Node {
   if len(children) == 1 {
      return Node{children[0], nil}
   } else {
      t := root
      t.Name=children[0]
      t.Children = append(t.Children, appendChild(root, children[1:]))
      return t
   }
}

有人能指出一个有效的解决方案吗?

【问题讨论】:

  • 您可以在 Google 上搜索 TrieRadix Tree 插入算法,以了解如何实现您想要的。
  • 如果您没有问题但想改进您的解决方案,您可以将类似的问题发布到 codereview.stackexchange
  • 实际上代码并没有真正起作用,但我会尝试你的建议

标签: recursion go tree


【解决方案1】:

https://play.golang.org/p/9pER5cwChF

func AddToTree(root []Node, names []string) []Node {
    if len(names) > 0 {
        var i int
        for i = 0; i < len(root); i++ {
            if root[i].Name == names[0] { //already in tree
                break
            }
        }
        if i == len(root) {
            root = append(root, Node{Name: names[0]})
        }
        root[i].Children = AddToTree(root[i].Children, names[1:])
    }
    return root
}

示例输出(请注意,我在 children 字段中使用了 omitempty,因为我不喜欢我的 JSON 中的 null 条目):

[{
    "name": "a",
    "children": [{
        "name": "b",
        "children": [{
            "name": "c"
        }, {
            "name": "g"
        }]
    }, {
        "name": "d"
    }]
}]

与您的版本的显着差异:

  • 它对节点列表而不是单个节点的子节点进行操作。这很重要,因为您的版本假定所有树都具有相同的单个根节点 (a),但实际情况可能并非如此。在您的版本中处理该问题的唯一方法是在根目录中添加一个“假”节点。
  • 它不重用输入节点。这是您的代码的主要问题之一。如果 len(children) > 1,则更新输入节点的名称,附加到它的子节点,然后递归。这意味着切片的每个先前级别都成为孩子的一部分。您需要创建一个 new 节点。
  • 它实际上是搜索树。您不是在搜索树以查看所插入的项目是否已经存在,因此您复制了节点(特别是节点 b)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    相关资源
    最近更新 更多