我想编写一个获取未排序列表的程序(可能包含重复值),并使用“累积”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))
答案 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))))))
现在,您可以根据foldr
和insert-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)