Scheme 如何修复快速排序实现?

Scheme 如何修复快速排序实现?,scheme,quicksort,Scheme,Quicksort,下面是我实现快速排序的尝试: (define (sublist ls start stop middle) (cond ( (null? ls) ls) ( (< middle start) (sublist (cdr ls) start stop (+ middle 1))) ( (> middle stop) '() ) (else (cons (car ls) (sublist (cdr ls) start stop (+ mid

下面是我实现快速排序的尝试:

(define (sublist ls start stop middle)
 (cond ( (null? ls) ls)
     ( (< middle start) (sublist (cdr ls) start stop (+ middle 1)))
     ( (> middle stop) '() )
     (else
        (cons (car ls) (sublist (cdr ls) start stop (+ middle 1))))))

(define (split5 ls)                                      
  (let ((len (length ls)))
   (cond ((= len 0) (list ls ls) )
         ((= len 1) (list ls '() ))
         (else 
          (list (sublist ls 1 (/ len 2) 1)
                (sublist ls (+(/ len 2)1) len 1))))))

;this divides the sorted list into two sublists 
(define (dividelist rel? ls)
 (split5 (order rel? ls)))


(define (quicksort rel? ls)
 (if (null? (cdr ls)) ls
  (let ((pivot (list-ref (sort rel? ls) (round (/ (length (sort rel? ls)) 2))))
        (left (car (dividelist rel? ls)))
        (right (cdr (dividelist rel? ls))))
        (join left pivot right))))

假设
order
过程与代码下面几行中使用的
sort
过程相同(等等,您正在使用排序过程来实现排序过程?!),并且
join
是一种
追加
,我可以得出结论,列表创建的问题在于
join
的实现。将其更改为此以修复它:

(define (join left pivot right)
  (append* left (list pivot) right))
现在,该过程将返回一个列表,如下所示:

(quicksort < '(9 3 -5 8 -7 2 9))
=> '(-7 -5 2 8 8 9 9)
或者使用Racket的高阶程序,稍微更华丽、更短:

(define (quicksort cmp lst)
  (if (empty? lst)
      empty
      (let ((x  (first lst))
            (xs (rest  lst)))
        (append (quicksort cmp (filter-not (curry cmp x) xs))
                (cons x (quicksort cmp (filter (curry cmp x) xs)))))))
另一种可能性是,使用
分区
在一个步骤中同时获得两个分区(轴之前的元素和轴之后的元素),效率更高:

(define (quicksort cmp lst)
  (if (empty? lst)
      empty
      (let-values (((greater-than less-equal)
                    (partition (curry cmp (first lst)) (rest lst))))
        (append (quicksort cmp less-equal)
                (cons (first lst) (quicksort cmp greater-than))))))
无论如何,它的工作原理与预期相符:

(quicksort < '(9 3 -5 8 -7 2 9))
=> '(-7 -5 2 3 8 9 9)
(快速排序<'(93-58-729))
=> '(-7 -5 2 3 8 9 9)

不应该
(右(cdr(dividelist rel?ls))
在快速排序结束时使用
cadr
而不是
cdr
?顺序在哪里?我希望这不是一个排序过程:P。另外,
join
过程在哪里?…是的,order使用排序过程。“那很糟糕吗?”泰勒18当然。使用
排序
实现
快速排序
没有意义。从头开始实现排序过程的整个想法是手动执行排序,在其中使用另一个排序过程是毫无意义的。快速排序不依赖于是否存在另一个排序过程,而且选择枢轴的方式显然是错误的。只需选择第一个元素。并使用我的答案中所示的
join
过程。
(define (quicksort cmp lst)
  (if (empty? lst)
      empty
      (let ((x  (first lst))
            (xs (rest  lst)))
        (append (quicksort cmp (filter-not (curry cmp x) xs))
                (cons x (quicksort cmp (filter (curry cmp x) xs)))))))
(define (quicksort cmp lst)
  (if (empty? lst)
      empty
      (let-values (((greater-than less-equal)
                    (partition (curry cmp (first lst)) (rest lst))))
        (append (quicksort cmp less-equal)
                (cons (first lst) (quicksort cmp greater-than))))))
(quicksort < '(9 3 -5 8 -7 2 9))
=> '(-7 -5 2 3 8 9 9)