在clojure中交换二进制树中的节点

时间:2015-08-23 06:38:06

标签: clojure

我正在尝试解决[this] [1]问题,你需要创建一个如下所示的二叉树:

              1
             / \
            2   3
           /    /
          4    5
         /    /
        /    /\
       /    /  \
       6   7    8
        \      / \
         \    /   \
          9  10   11

从此输入中,-1表示空节点

[2 3] [4 -1] [5 -1] [6 -1] [7 8] [-1 9] [-1 -1] [10 11] [-1 -1] [-1 -1] [-1 -1]

完成后,问题会要求您在给定深度交换节点。

到目前为止,我有了创建树的代码:

(ns scratch.core
  (require [clojure.string :as str :only (split-lines join split)]))

(defn numberify [str]
  (vec (map read-string (str/split str #" "))))

(defrecord TreeNode [val left right])

(defn preprocess-input [n xs]
  (let [source (map vector (range 1 n) xs)]
    (->> source
         (map (fn [[k v]]
                {k v}))
         (into {}))))

(defn build-tree [val source]
  (when-let [[l r] (get source val)]
    (TreeNode. val (build-tree l source) (build-tree r source))))

(let [input "11\n2 3\n4 -1\n5 -1\n6 -1\n7 8\n-1 9\n-1 -1\n10 11\n-1 -1\n-1 -1\n-1 -1\n2\n2\n4"
      lines (str/split-lines input)
      tree-length (read-string (first lines))
      tree-lines (map numberify (drop 1 (take (inc tree-length) lines)))
      tree-source (preprocess-input tree-length tree-lines)
      tree (build-tree 1 tree-source)
      swap-depths (map read-string (vec (take-last (Integer/parseInt (get lines (inc tree-length))) lines)))])

我完全不知道如何交换节点,我尝试过这个功能:

(defn walk-tree [node curr swap-depth]
  (when node
    (let [left (:left node)
          right (:right node)
          val (:val node)]
      (if (= curr swap-depth)
        (TreeNode. val (walk-tree right (inc curr) swap-depth) (walk-tree left (inc curr) swap-depth))
    (TreeNode. val (walk-tree left (inc curr) swap-depth) (walk-tree right (inc curr) swap-depth))))))

但我认为我应该使用BFS而不是DFS,因为虽然我可以通过这种方式交换节点,但是当遇到正确的节点时它会被换回。

1 个答案:

答案 0 :(得分:1)

就像我在评论中所说,我会以这两种方式解决这个问题:

  1. 将此作为字符串操作问题。首先将其拆分为一系列线条。然后定义一个采用ma-seq的函数,并从m中获取第一个a-seq元素,并生成一个n n表示该层中有效节点的数量和剩余的seq。重复此depth次,您现在处于给定的深度。做任何要求。还应该有其他可行的方法。
  2. 构建一个树状结构。但是,不是简单地保持每个节点给出的值,而是附加深度。然后使用clojure.walk/postwalk遍历树,在查看给定深度的节点时更新值。