这是我尝试实施快速排序:
(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))))
我知道这种实现效率很低,但我想不出办法。无论如何,它并没有真正起作用。
When I input this:
(quicksort < '(9 3 -5 8 -7 2 9))
It gives me this:
(-7 -5 2 8 (8 9 9))
It should give me this:
(-7 -5 2 3 8 9 9)
我该如何解决这个问题?
修改
(define (join ls1 goo ls2)
(if (null? ls1) (cons goo ls2)
(if (null? ls2) (cons goo ls1)
(cons (car ls1) (join (cdr ls1) goo ls2)))))
答案 0 :(得分:1)
假设order
过程与代码中使用下面几行的sort
过程相同(等等,您是否正在使用排序过程来实现排序过程?!)和join
是某种append
,我可以得出结论,列表创建问题出现在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)
哎呀,数字3
去了哪里?您的代码中存在错误,您必须找到它!提示:计算枢轴的代码非常错误。
修改强>
这是一个正确,无障碍的QuickSort实现。请注意,在这样的简单实现中,它足以选择第一个元素作为轴:
(define (quicksort cmp lst)
(if (null? lst)
'()
(let ((x (car lst))
(xs (cdr lst)))
(append (quicksort cmp (filter (lambda (e) (cmp e x)) xs))
(list x)
(quicksort cmp (filter (lambda (e) (not (cmp e x))) xs))))))
或使用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)))))))
另一种可能性,使用partition
在一个步骤中获取两个分区(枢轴之前的元素和枢轴之后的元素) - 它更有效:
(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)