对Clojure来说很新,我还不知道如何做到这一点,我需要遍历一个预制的二叉搜索树,并计算2个差异子树中的节点数,如此问题
感谢您提供任何帮助,只需要推动即可开始
(defn familytree [tree i x]
(cond
(= (first(tree) i) )
(count (zip/children))
(= (first(tree) x))
(count (zip/children))
:else
(familytree (rest tree)x i)
))
输入数据
(def test1 '[ 1 [ 2 [ 4 [8 9 ] 5 [ 10 11 ]] 3 [ 6 [ 12 13 ] 7 [ 14 15 ]]]])
答案 0 :(得分:2)
卡梅伦
首先确定您将存储信息的Clojure持久数据类型。一旦确定:
<强>更新强>
以下是我对要求的理解:
鉴于此,我决定使用zipper
,因为它合理地证明了逻辑的分解以达到需求目标。我还抽象了各个方面,因此计算儿童的谓词可能会发生变化。
您需要阅读clojure.zip
(网上有大量关于此的信息。
计数器
现在覆盖了核心遍历(zippers
),让我们从计数功能开始。根据要求:无论我如何到达节点,我都想计算节点的子节点:
(defn count-children-at-node
"Takes a zipper location and counts
elements of it's chidren vector. Uses flatten on the
children to sequence all the elements for counting.
Returns a tuple identifiying the node and it's children count"
[loc]
(let [cnodes (zip/right loc)]
[:node (zip/node loc)
:count (if (nil? cnodes) ; test for no children
0
(count (flatten (zip/node cnodes))))]))
The Workhorse 这是遍历发生的地方。它将是详尽的,以便找到所有可能感兴趣的节点。计数也将包括在内(见下面的结果)。我还想积累我的结果并具有灵活的谓词函数来测试结果中的包含:
(defn find-nodes-to-count
"Accumulate results of performing a reduction function on a node in
the tree that matches the predicate criteria"
[acc predfn redfn loc]
(if (zip/end? loc)
acc
(if (predfn (zip/node loc))
(recur (conj acc (redfn loc)) predfn redfn (zip/next loc))
(recur acc predfn redfn (zip/next loc)))))
包装器 使用我的核心计数器和遍历机制,使用简单的包装功能来运用核心:
(defn nodes-counter
"Takes a tree collection and variable number of node identifiers
and return an accumulation of tuples, each identifying the node and it's children
count"
[coll & nodevals]
(find-nodes-to-count
[] ; accumultator
#(contains? (into #{} nodevals) %) ; predicate function
count-children-at-node ; reduction function
(zip/vector-zip coll))) ; the tree collection
<强>测试/验证强>
使用节点标识符变体调用nodes-counter
的一些REPL示例:
(def mytree [1 [2 [4 [8 9] 5 [ 10 11 ]] 3 [ 6 [ 12 13 ] 7 [ 14 15 ]]]])
(nodes-counter mytree 16) ; => []
(nodes-counter mytree 15) ; => [[:node 15 :count 0]]
(nodes-counter mytree 2 4) ; => [[:node 2 :count 6] [:node 4 :count 2]]
(nodes-counter mytree 4 2) ; => [[:node 2 :count 6] [:node 4 :count 2]]