用scheme最基本的元素定义排序函数

用到的元素有9个:

define,if,null?,cons car,cdr,lambda,let,named let,

其实let 和 named let可以去掉.但那样会带来性能和可读性下降的问题.

排序类型选的是经典的快速排序.

;筛选函数
(define (filter f x)
  (let recur ((x x))
    (if (null? x)
        '()
        (if (f (car x))
            (cons (car x) (recur (cdr x)))
            (recur (cdr x))))))

;三元合并函数,形如'(1 2) , 3 , '(4 5)合并为'(1 2 3 4 5)
(define (merge x y z)
  (let recur ((x x))
    (if (null? x)
        (cons y z)
        (cons (car x) (recur (cdr x))))))

;最原始的排序函数形式(升序)
(define (sorted x)
  (if (null? x)
      '()
      (if (null? (cdr x))
          x
          (merge (sorted (filter (lambda (i) (< i (car x))) (cdr x))) 
                 (car x) 
                 (sorted (filter (lambda (i) (>= i (car x))) (cdr x)))))))

;加入默认参数功能,控制升降序且高性能版本
(define (sort x . y)
  (let ((lef (if (null? y) < (if (= (car y) 0) < >=)))
        (rig (if (null? y) >= (if (= (car y) 0) >= <))))
    (let recur ((x x))
      (if (null? x)
          '()
          (let ((fir (car x))(rest (cdr x)))
            (if (null? rest)
                x
                (merge (recur (filter (lambda (i) (lef i fir)) rest)) 
                       fir 
                       (recur (filter (lambda (i) (rig i fir)) rest)))))))))

(sorted '(4 3 2 1 0))
(sort '(4 3 2 1 0) 0)
(sort '(4 3 2 1 0))
(sort '(5 6 7 8 9) 1)
(sort '(5 6 7 8 9))

结果:

(0 1 2 3 4)
(0 1 2 3 4)
(0 1 2 3 4)
(9 8 7 6 5)
(5 6 7 8 9)
> 

 

这次的主要收获是发现应该大胆采用let来避免重复计算,例子中的lef, rig, fir, rest 就是很好的证明.

不要觉得这样会导致代码层次过多,性能才更重要.

更何况有时let也能提高可读性.

posted @ 2013-10-28 01:50  LisPythoniC  阅读(614)  评论(0编辑  收藏  举报