我有一个节点列表,每个节点都有一个父节点,我想用这些节点构建一棵树。
(def elems '[{:node A :parent nil} {:node B :parent A} {:node C :parent A} {:node D :parent C}])
(build-tree elems)
=> (A (B) (C (D)))
目前我有这个代码:
(defn root-node [elems]
(:node (first (remove :parent elems))))
(defn children [elems root]
(map :node (filter #(= root (:parent %)) elems)))
(defn create-sub-tree [elems root-node]
(conj (map #(create-sub-tree elems %) (children elems root-node)) root-node))
(defn build-tree [elems]
(create-sub-tree elems (root-node elems)))
在此解决方案中使用递归,但不使用循环递归语法。这很糟糕,因为代码无法优化并且StackOverflowError 是可能的。
如果我在每个步骤中都有一个递归,我似乎只能使用 recur。
在树的情况下,我对节点的每个子节点都有一个递归。
我正在寻找不会遇到此问题的调整解决方案。
如果您对此问题有完全不同的解决方案,我很乐意看到它。
我读了一些关于 zipper 的文章,也许这是构建树的更好方法。