方案 - 使用累积排序

时间:2012-05-11 15:34:49

标签: sorting scheme fold accumulate

我想编写一个获取未排序列表的程序(可能包含重复值),并使用“累积”a.k.a foldr,reduce等对其进行排序。

我成功过滤了双值,但无法对其进行排序。通常,我无法看到我如何使用地图,过滤,累积来对其进行排序....

我必须完成它而不使用插入排序,冒泡排序......

这是我现在的代码

(累积(lambda(x no-duplicate)(cons x(filter(lambda(z)(not(= xz)))no-duplicate)))'()(list 1 2 0 66 3 4))

3 个答案:

答案 0 :(得分:3)

您可以简单地实现插入排序。

累计值是到目前为止看到的所有值的排序列表。 当看到新值时,它将被插入到排序列表中 在正确的地方。与此相同,使用相同的insert 将在insert-sort的普通实现中。

您必须编写的是一个函数insert,它给定一个元素x,一个排序列表ys返回一个包含x和ys中所有元素的排序列表。将此函数与accumulate一起使用,一次构建一个元素的最终结果。

答案 1 :(得分:1)

另一种方法是tree sort,就像插入排序(@ soegaard' s解决方案),但具有更好的时间复杂度。在这里,您从一个空树开始作为初始值,并在每次折叠迭代时构建树。

答案 2 :(得分:1)

借用@soegaards的回答:首先定义一个给定元素,比较过程和列表的插入过程,根据比较过程返回一个包含元素的新列表:

(define (insert-in-order e cmp lst)
  (cond ((null? lst)
         (list e))
        ((cmp e (car lst))
         (cons e lst))
        (else
         (cons (car lst) (insert-in-order e cmp (cdr lst))))))

现在,您可以根据foldrinsert-in-order实现插入排序过程,它接收要排序的列表和比较过程作为参数:

(define (insertion-sort lst cmp)
  (foldr (lambda (e acc)
           (insert-in-order e cmp acc))
         '()
         lst))

像这样使用:

(insertion-sort '(4 5 1 1 2 3) <) ; ascending order
> '(1 1 2 3 4 5)

(insertion-sort '(4 5 1 1 2 3) >) ; descending order
> '(5 4 3 2 1 1)