我试图用非平凡的(即不是斐波那契)来解决Clojure中的核心运行,但是可以管理的例子。显然,可以使用corecursion实现二叉树遍历。维基百科在Python中有一个我无法理解的例子。
如何在Clojure中实现它?假设我正在寻找BFS,但它可能是任何订单。
这是我到目前为止所拥有的:
(defstruct tree :val :left :right)
(def my-tree (struct tree 1 (struct tree 2) (struct tree 3 4 5)))
(def bfs (lazy-cat [my-tree] (map #(:left %) bfs) (map #(:right %) bfs) ))
(println (take 4 bfs))
不幸的是,它似乎一路向左,忽略了正确的分支。
答案 0 :(得分:8)
假设Michal的代码符合您的要求,这也有效:
(defn bftrav [& trees]
(when trees
(concat trees
(->> trees
(mapcat #(vector (:left %) (:right%)))
(filter identity)
(apply bftrav)))))
答案 1 :(得分:2)
以下是维基百科文章中bftrav
Haskell函数的直接翻译。请注意,它使用我刚刚撰写的letrec
宏 - 请参阅this Gist了解最新版本。
我已将my-tree
的定义更改为:
(def my-tree (struct tree 1 (struct tree 2) (struct tree 3 (struct tree 4) (struct tree 5))))
此外,我的leaf?
函数假设我们只处理正确的双向分支和叶节点(因此nil
分支上的:left
意味着{{1}在nil
分支上);改变这一点来处理单子“分支”应该不难两个:
:right
(defn leaf? [t] (nil? (:left t)))
的代码如下:
bftrav
REPL的一个例子:
(defn bftrav [t]
(letrec [queue (lazy-seq (cons t (trav 1 queue)))
trav (fn [l q]
(lazy-seq
(cond (zero? l) nil
(leaf? (first q)) (trav (dec l) (rest q))
:else (let [{:keys [left right]} (first q)]
(cons left (cons right (trav (inc l) (rest q))))))))]
queue))