【问题标题】:Tree from adjacency map邻接图的树
【发布时间】:2013-01-19 22:55:17
【问题描述】:

我正在尝试创建一个从{node [children]} 形式的邻接列表构建树的函数。

(def adjacency
  {nil [:a]
   :a [:b :c]
   :b [:d :e]
   :c [:f]})

这应该会导致

{nil {:a {:b {:d nil
              :e nil}
          :c {:f nil}}}}

无论我怎么尝试,我都无法让它工作。递归是我的一个弱点,我发现的大多数递归示例只处理列表的递归,而不是树。

已编辑:由于在发布时没有编辑器和原始来源,原始数据集和结果无意中嵌套得太深。对此感到抱歉。

【问题讨论】:

    标签: recursion clojure tree adjacency-list


    【解决方案1】:

    adjacency 的每个子图中只有一个条目。这是必要的吗?结果tree也有同样的问题。

    我希望它会更清楚:

    (def adjacency {:a [:b :c]
                    :b [:d :e]
                    :c [:f]})
    

    所以解决办法是:

    (defn tree [m root]
      (letfn [(tree* [l]
                (if (contains? m l)
                  {l (into {} (map tree* (m l)))}
                  [l nil]))]
        (tree* root)))
    

    测试:

    (tree adjacency :a)
    => {:a {:b {:d nil
                :e nil}
            :c {:f nil}}}
    

    更新。如果您不需要将结果树作为嵌套映射

    (defn tree [m root]
      (letfn [(tree* [l]
                (if (contains? m l)
                  (list l (map tree* (m l)))
                  (list l nil)))]
        (tree* root)))
    
    (tree adjacency :a)
    => (:a ((:b ((:d nil)
                 (:e nil)))
            (:c ((:f nil)))))
    

    【讨论】:

      【解决方案2】:

      在处理树木时,我通常更喜欢使用clojure.walk。 我假设根节点在adjacency 向量中的第一个。

      (use 'clojure.walk)
      
      (def adjacency
        [{nil [:a]}
         {:a [:b :c]}
         {:b [:d :e]}
         {:c [:f]}])
      
      (prewalk
       (fn [x]
         (if (vector? x)
           (let [[k v] x lookup (into {} adjacency)]
             [k (into {} (map (fn [kk] [kk (lookup kk)]) v))])
           x))
       (first adjacency))
      

      结果:{nil {:a {:b {:d {}, :e {}}, :c {:f {}}}}}

      注意:空子元素表示为 {} 而不是 nil,子元素也是地图而不是矢量,因为地图可以轻松导航这棵树。

      【讨论】:

        猜你喜欢
        • 2011-07-16
        • 1970-01-01
        • 1970-01-01
        • 2020-07-02
        • 1970-01-01
        • 1970-01-01
        • 2020-11-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多