如,反向之前'(1 2 3)
,
反向之后变为'(3 2 1)
R7RS的(scheme base)
提供了reverse
,没有副作用,纯的函数式版本。(srfi 1)
提供了mutation版本reverse!
,会改变原有列表的结果,有副作用。
不管有无副作用,实现的思路是一样的。给出实现:
(1)“Pure“版本my-reverse
(define my-reverse
(lambda (ls)
(let f ([ls ls] [new '()])
(if (null? ls)
new
(f (cdr ls) (cons (car ls) new))))))
(2)“Mutation“版本my-reverse!
(define my-reverse!
(lambda (ls)
(let f ([ls ls] [new '()])
(if (null? ls)
new
(let ([t (cdr ls)]) (set-cdr! ls new) (f t ls))))))
唯一的区别是:(1)用cons
建立新列表,而(2)使用set-cdr!
改变列表元素间的连接关系。
图示如下,实线是反向前原有列表元素连接关系,虚线是反向后元素连接关系。注意:(eq? '() '())
为#t
,'()
是唯一的,所以所有列表结尾都指向同一个'()
。
pure版本
mutation版本
——-2015/12/20 更新——–
使用fold-left
更简单
(import (srfi 1))
(define my-reverse
(lambda (ls)
(fold-left (lambda (a e)
(cons e a))
'()
ls)))