Scheme中的冒泡排序
Posted
技术标签:
【中文标题】Scheme中的冒泡排序【英文标题】:Bubble Sorting in Scheme 【发布时间】:2013-10-16 03:33:26 【问题描述】:我正在为冒泡排序编写递归代码(通过交换从最小到最大) 我有一个代码只做一次冒泡排序
(define (bubble-up L)
(if (null? (cdr L))
L
(if (< (car L) (cadr L))
(cons (car L) (bubble-up (cdr L)))
(cons (cadr L) (bubble-up (cons (car L) (cddr L))))
)
)
如果我在这段代码中放入一个列表,它会返回最后一个数字最大的列表 例如..(冒泡'(8 9 4 2 6 7))->'(8 4 2 6 7 9)
现在我正在尝试编写代码来执行(冒泡 L)N 次(列表中的整数个数) 我有这个代码:
(define (bubble-sort-aux N L)
(cond ((= N 1) (bubble-up L))
(else (bubble-sort-aux (- N 1) L)
(bubble-up L))))
(bubble-sort-aux 6 (list 8 9 4 2 6 7)) -> ' (8 4 2 6 7 9)
但递归似乎没有发生,因为它只排序一次! 欢迎任何建议,我只是难住了!
【问题讨论】:
“我正在为冒泡排序编写递归代码” - 不要!! @MitchWheat AveryPoole 正在使用 Scheme 编写,其中尾调用优化是规范要求的。迭代通常通过 Scheme 中的尾递归来实现。 Recusion 是在Scheme中实现这一点的自然方式。 有替代方法吗?刚开始写代码,尾递归是我学到的唯一方法。 @MitchWheat @Joshua Taylor:我指的是一般使用 BubbleSort。 Scheme(至少 R5RS)支持do
迭代构造,但在 Scheme 中看到尾递归用于表达迭代将更加常见。例如,ÓscarLópez 的答案表面上是递归的,但因为对 bubble-sort-aux
的调用处于尾部位置,所以它本质上是迭代的。不过,您的 bubble-up
不是 尾递归的。您也可以考虑尝试使其尾递归。
【参考方案1】:
试试这个:
(define (bubble-sort-aux N L)
(cond ((= N 1) (bubble-up L))
(else (bubble-sort-aux (- N 1) (bubble-up L)))))
如果您继续“冒泡”列表N
次,它将在最后进行排序。您的代码的问题是您没有使用 bubble-up
的结果做任何事情 - 但是如果我们将 bubble-up
返回的值传递给函数的下一次调用,它最终会被排序。现在程序按预期工作:
(bubble-sort-aux 6 (list 8 9 4 2 6 7))
=> '(2 4 6 7 8 9)
【讨论】:
非常感谢奥斯卡!我觉得我有点筋疲力尽了,那是个大错误 =/【参考方案2】:我的实现:
(define (bubble-swap ls)
(if (null? (cdr ls))
ls
(if (> (car ls) (cadr ls))
(cons (cadr ls) (bubble-swap (cons (car ls) (cddr ls))))
(cons (car ls) (bubble-swap (cdr ls))))))
(define (len ls)
(if (null? ls)
0
(+ 1 (len (cdr ls)))))
(define (bubblesort_ ls n)
(if (= n 1)
ls
(bubblesort_ (bubble-swap ls) (- n 1))))
(define (bubblesort ls) (bubblesort_ ls (len ls)))
我实现了自定义 len
函数,但您可以使用标准 length
函数(如果可用)。
【讨论】:
以上是关于Scheme中的冒泡排序的主要内容,如果未能解决你的问题,请参考以下文章