在scheme中对列表排序

在scheme中对列表排序,scheme,Scheme,我想创建对列表排序的函数。例如,我有以下列表: x1, x2, x3 .... xn 或 1,2,3,4,5,6 我想按以下顺序显示数字: x1, xn, x2, xn-1 或 你能帮我写一下这个例子吗?通常,当我们谈到排序时,我们指的是根据项目内容的某些特征对项目进行排序,而不是项目在列表中的位置。我会把你的情况称为排列,但也许有些人也会对这种用法提出异议。:-) 以下是解决问题的方法: 在中间分割列表(如果你只想遍历该列表,你可以使用龟兔);如果需要,可以调用那些列表head和tail

我想创建对列表排序的函数。例如,我有以下列表:

x1, x2, x3 .... xn

1,2,3,4,5,6

我想按以下顺序显示数字:

x1, xn, x2, xn-1


你能帮我写一下这个例子吗?

通常,当我们谈到排序时,我们指的是根据项目内容的某些特征对项目进行排序,而不是项目在列表中的位置。我会把你的情况称为排列,但也许有些人也会对这种用法提出异议。:-)

以下是解决问题的方法:

  • 在中间分割列表(如果你只想遍历该列表,你可以使用龟兔);如果需要,可以调用那些列表
    head
    tail
  • 反转
    尾部
    列表,并将其与
    头部
    列表交错
  • 另一种方法:

  • 反转原始列表对(我们称之为
    rev
  • 将原始列表与
    rev
    交错,跟踪每次遍历的元素。当他们在中间相遇时,停下来。
  • 这里演示了第二种方法(需要加载):


    这不是真正的排序操作,更像是洗牌;这里有另一种解决方法。首先,让我们定义
    interleave
    过程,该过程交替两个列表中的元素,返回单个列表:

    (define (interleave l1 l2)
      (cond ((empty? l1) l2)
            ((empty? l2) l1)
            (else (cons (first l1)
                        (interleave l2 (rest l1))))))
    
    现在我们取原始列表和中间部分(这是一个特定于球拍的程序);最后,我们将两个结果列表交错排列,颠倒尾部:

    (define (zippy lst)
      (let-values (((head tail) (split-at lst (quotient (length lst) 2))))
        (interleave head (reverse tail))))
    
    上面的IMHO实现更加直观,如果您使用Racket,则不需要外部库。它按预期工作:

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

    ……斯卡尔·洛佩斯的回答证明了第一种方法+1非常好。:-)非Racket实现的注意事项:
    splitat
    是的一部分,而
    let values
    是的一部分。如果您的实现没有SRFI 11,您还可以轻松地转换为使用
    receive
    from,或者您也可以直接使用
    call with value
    ,尽管后者更难看。:-)顺便说一句,我认为
    (/(length lst)2)
    为奇数长度的列表返回一个非整数,而
    处拆分可能不喜欢<代码>(商(长度lst)2)
    可能会更好。@ChrisJester Young你当然是对的。修好了,谢谢!我看到一个问题。如果我有以下顺序,如何对数字进行排序:
    4,2,9,3,5,1
    如何对它们进行排序?您在问题中定义的顺序似乎取决于元素的位置,而不是它们的值。如果值相关,则在将列表提供给我的函数之前,先对列表进行排序,然后使用
    排序
    过程
    (define (zippy lst)
      (let-values (((head tail) (split-at lst (quotient (length lst) 2))))
        (interleave head (reverse tail))))
    
    (zippy '(1 2 3 4 5 6))
    => '(1 6 2 5 3 4)