理解“欢乐的Clojure”中提出的懒惰快速排序的输入

时间:2014-07-31 09:10:06

标签: algorithm clojure

我从The Clojure中复制了懒惰的快速排序实现 并在循环后添加了两个println语句,以更好地理解输入的工作原理(参见底部的实现)。

运行(qsort [2 1 4 3])时,我得到了这个输出:

Work: = ([2 1 4 3]) =
Part: = [2 1 4 3] & nil =
=pivot:  2 =
Work: = ([2 1 4 3]) =
Part: = (1) & (2 (4 3)) =
[...]

正如所料。我不明白的是工作的结构。 Work如何只是包含向量的列表,part & parts(1) & (2 (4 3))Work不应具有以下结构[(1) (2 (4 3))]


完整性的快速排序实现:

(defn sort-parts
  "Lazy, tail-recursive, incremental quicksort. Works against and
creates partitions based on the pivot, defined as 'work'."
  [work]
  (lazy-seq
   (loop [[part & parts] work]
     (println "Work: =" work "=")
     (println "Part: =" part "&" parts "=")
     (if-let [[pivot & xs] (seq part)]
       (do (println "=pivot: " pivot "=")
           (let [smaller? #(< % pivot)]
             (recur (list*
                     (filter smaller? xs)
                     pivot
                     (remove smaller? xs)
                     parts))))
       (when-let [[x & parts] parts]
         (println "output")
         (cons x (sort-parts parts)))))))

(defn qsort [xs]
  (sort-parts (list xs)))

1 个答案:

答案 0 :(得分:4)

你的

(println "Work: =" work "=")

不会打印您在work表单中看到的loop

它打印work参数列表中的外sort-parts个边界。只有在调用sort-parts时才会更改。

要获得预期结果,请更改:

 (loop [[part & parts] work]

 (loop [[part & parts :as work] work]

这样就可以将工作绑定到整个循环参数列表。