使用过滤器

时间:2015-11-05 09:27:25

标签: sorting recursion scheme racket quicksort

我需要编写函数(快速排序pred lst) lst 是要排序的数字列表 pred 是排序列表的谓词,此谓词的签名为:(lambda(x y)...)

- (quick-sort < lst) will sort ascending (small to large)
- (quick-sort > lst) will sort descending (large to small)
- (quick-sort (lambda (x y) (< (car x) (car y))) lst) will sort a list
with inner lists according to the first element of the inner list, ascending.

我从常规的快速排序开始:

(define (quick-sort lst)
  (cond
    ((null? lst)        '())
    ((= (length lst) 1) lst)
    (else               (append (quick-sort (filter (lambda (n) (< n (car lst))) lst))
                                (list (car lst))
                                (quick-sort (filter (lambda (n) (> n (car lst))) lst))))))

现在我正试图用pred做这个:

(define (quick-sort pred lst)
  (define (quick-sort-help lst)
    (cond   ((null? lst) ())
        ((= (length lst) 1) lst)
        (else 
            (append (quick-sort-help (filter (lambda (n) (pred n (car lst))) lst))
                (list (car lst))
                (quick-sort-help (filter (lambda (n) (not(pred n (car lst)))) lst)))))) (quick-sort-help lst))

我得到了无限的递归或其他东西。

你可以帮我解决这个问题吗? 谢谢!

1 个答案:

答案 0 :(得分:1)

首先,您不需要辅助函数quick-sort-help

它无限次地重复,因为您将辅助函数应用于lst而不是cdr lst。在常规快速排行榜中,您有(filter (lambda (n) (< n (car lst)))(filter (lambda (n) (> n (car lst)))。但是在带有谓词的那个中,如果谓词是(not (pred ...),那么<=将涵盖<而不是>的案例,反之亦然。因此它会被卡住,因为列表中的第一个元素总是与它自身相等。

这是一个正确的快速排序:

(define (qsort f lst)
  (if (null? lst)
      null
      (let ([pivot (car lst)])
        (append (qsort f (filter (λ (n) (f n pivot)) (cdr lst)))
                (list pivot)
                (qsort f (filter (λ (n) (not (f n pivot))) (cdr lst)))))))