我从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)))
答案 0 :(得分:4)
你的
(println "Work: =" work "=")
不会打印您在work
表单中看到的loop
。
它打印work
参数列表中的外sort-parts
个边界。只有在调用sort-parts
时才会更改。
要获得预期结果,请更改:
(loop [[part & parts] work]
到
(loop [[part & parts :as work] work]
这样就可以将工作绑定到整个循环参数列表。