Clojure - 排序功能

时间:2014-09-05 05:22:50

标签: clojure

我正在尝试编写一个递归排序函数,将列表从低到高(duh)排序。我目前正在获得输出,而不是正确的输出。这是我的代码:

(defn sort/predicate [pred loi]
   (if (empty? loi)
     ()
     (if (= (count loi) 1)
       (cons (first loi) (sort pred (rest loi)))
       (if (pred (first loi) (first (rest loi)))
         (cons (first loi) (sort pred (rest loi)))
         (if (pred (first (rest loi)) (first loi))
           (cons (first (rest loi)) (sort pred (cons (first loi) (rest (rest loi)))))
           (cons (first loi) (sort pred (rest loi))))))))

基本上,我比较列表中的前两个元素,如果第一个元素较小,我将其与比较列表的下两个元素的结果相比较。如果列表的第二个元素较小,我将第二个元素与第一个元素的前两个元素和第二个元素之后的所有元素进行排序(对不起,如果这很难遵循)。然后,当列表中只剩下一个元素时,我将它扔到最后并返回它。但是,在某个地方有一个bug,因为我应该得到以下内容:

>(sort/predicate < '(8 2 5 2 3))
(2 2 3 5 8)

但相反,我得到:

>(sort/predicate < '(8 2 5 2 3))
(2 5 2 3 8)

我对clojure很新,所以非常感谢任何帮助。另外,我想保持我的代码大致相同(我不想使用已经存在的排序功能)。感谢

3 个答案:

答案 0 :(得分:1)

我不认为这是一种非常有效的排序方式,但我试图坚持你的意图:

(defn my-sort [cmp-fn [x & xs]]
  (cond
    (nil? x) '()
    (empty? xs) (list x)
    :else (let [[y & ys :as s] (my-sort cmp-fn xs)]
            (if (cmp-fn x y)
              (cons x s)
              (cons y (my-sort cmp-fn (cons x ys)))))))

答案 1 :(得分:0)

;;合并排序实现-无需占用堆栈的递归排序

(defn merge-sort
  ([v comp-fn]
   (if (< (count v) 2) v
     (let [[left right] (split-at (quot (count v) 2) v)]
       (loop [result       []
              sorted-left  (merge-sort left comp-fn)
              sorted-right (merge-sort right comp-fn)]
         (cond
           (empty? sorted-left) (into result sorted-right)
           (empty? sorted-right) (into result sorted-left)
           :else (if (comp-fn 0 (compare (first sorted-left) (first sorted-right)))
                   (recur (conj result (first sorted-left)) (rest sorted-left) sorted-right)
                   (recur (conj  result (first sorted-right))  sorted-left (rest sorted-right))))))))
  ([v] (merge-sort v >)))

答案 2 :(得分:-2)

clojure.core/sort由Java实现更通用。

user=> (sort '(8 2 5 2 3))
(2 2 3 5 8)
user=> (sort > '(8 2 5 2 3))
(8 5 3 2 2)
user=> (source sort)
(defn sort
  "Returns a sorted sequence of the items in coll. If no comparator is
  supplied, uses compare.  comparator must implement
  java.util.Comparator.  If coll is a Java array, it will be modified.
  To avoid this, sort a copy of the array."
  {:added "1.0"
   :static true}
  ([coll]
   (sort compare coll))
  ([^java.util.Comparator comp coll]
   (if (seq coll)
     (let [a (to-array coll)]
       (. java.util.Arrays (sort a comp))
       (seq a))
     ())))
nil
user=>