Sort a list in scheme

此生再无相见时 提交于 2019-12-02 02:20:27

问题


I want to create function which sorts list. For example I have this list:

x1, x2, x3 .... xn

or

1, 2, 3, 4, 5, 6

I want to display the numbers in this order:

x1, xn, x2, xn-1

or

1, 6, 2, 5, 3, 4

Can you help me to write this example?


回答1:


Usually when we talk about sorting, we refer to ordering the items by some characteristic of the item contents, not the item position in the list. I would call your situation permuting, but perhaps some people might dispute that usage, too. :-)

Here's how you might approach the problem:

  1. Split the list in the middle (you can do this using tortoise-and-hare if you only want to traverse the list once); call those lists head and tail, if you want.
  2. Reverse the tail list, and interleave it with the head list.

Another approach:

  1. Reverse the original list pairs (let's call it rev).
  2. Interleave the original list with rev, keeping track of the element traversed each time. When they meet in the middle, stop.

Here's a demonstration of the second approach (requires SRFI 1 to be loaded):

(define (zippy lst)
  (if (null? lst)
      '()
      (let recur ((lst lst)
                  (rev (pair-fold cons '() lst)))
        (cond ((eq? lst (car rev)) (list (car lst)))
              ((eq? (cdr lst) (car rev)) (list (car lst) (caar rev)))
              (else (cons* (car lst) (caar rev)
                           (recur (cdr lst) (cdr rev))))))))



回答2:


This is not really a sorting operation, more like a shuffling; here's another way to solve it. First, let's define the interleave procedure that alternates elements from two lists, returning a single list:

(define (interleave l1 l2)
  (cond ((empty? l1) l2)
        ((empty? l2) l1)
        (else (cons (first l1)
                    (interleave l2 (rest l1))))))

Now we take the original list and split-at the middle (this is a Racket-specific procedure); finally we interleave the two resulting lists, reversing the tail:

(define (zippy lst)
  (let-values (((head tail) (split-at lst (quotient (length lst) 2))))
    (interleave head (reverse tail))))

The above implementation IMHO is a bit more intuitive, and if you're working with Racket it doesn't require external libraries. It works as expected:

(zippy '(1 2 3 4 5 6))
=> '(1 6 2 5 3 4)


来源:https://stackoverflow.com/questions/16797858/sort-a-list-in-scheme

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!