Why list-ref can not got the correct parameter?
I wrote a quick-sort in scheme (racket)
#lang racket
(define (quick-sort xs)
(let* ([p (list-ref xs 0)]
[tail (list-tail xs 1)]
[less (filter (lambda (x) (< x p)) tail)]
[greater (filter (lambda (x) (>= x p)) tail)])
(append (quick-sort less) (list p) (quick-sort greater))))
But when I tried it I got this error:
> (quick-sort (list 99 2 9922))
list-ref: index 0 too large for list: '()
I'm new to scheme so I don't quite understand why list-ref can't get the correct input '(99 2 9922)
Edit:
Thanks. I made it work.
#lang racket
(define (quick-sort xs)
(let* ([p (first xs)]
[tail (rest xs)]
[less (filter (lambda (x) (< x p)) tail)]
[greater (filter (lambda (x) (>= x p)) tail)])
开发者_运维问答 (if (equal? (length xs) 1)
xs
(append (quick-sort less) (list p) (quick-sort greater)))))
When designing a recursive algorithm, two things are crucial: your terminating condition and your recursive step, and you don't have a terminating condition. Trace what your code is doing: During your first execution of quick-sort
, you'll call:
(append (quick-sort (list 2)) (list 99) (quick-sort (list 9922)))
And the first quick-sort
call will in turn invoke (quick-sort '())
. Your code doesn't handle the empty list very gracefully, as it will always try to reference the first element of the array as the first thing it does.
Add logic to gracefully handle the empty list.
Also, using first
and rest
to get the first and remaining elements of a list is considered to be much more pragmatic.
Your code is missing the base case, when the input list is empty. When that happens, list-ref
fails with that error.
BTW, note that a better name for (list-ref l 0)
is (first l)
, and similarly (list-tail l 1)
is better written as (rest l)
.
(There's also car
and cdr
, but if you're a newbie you can ignore them for now.)
You probably already know this, but Racket comes with a built-in sort function too.
精彩评论