【问题标题】:Bubble Sorting with Scheme带方案的冒泡排序
【发布时间】:2014-03-17 10:38:12
【问题描述】:

我正致力于在 Scheme 中实现冒泡排序算法,我必须说,函数式编程方式是一个奇怪的概念,我很难掌握它。

我已经成功地创建了一个函数,它会冒出我们遇到的第一个最大值,但这就是它的全部作用。

(bubbleH '(5 10 9 8 7))
(5 9 8 7 10)

我正在努力使用完全循环列表直到没有进行交换所需的辅助函数。

这是我目前所处的位置,显然这是不正确的,但我认为我走在正确的轨道上。我知道我可以自己传递列表中的元素数量,但我正在寻找与此不同的解决方案。

(define bubbaS
  (lambda (lst)
  (cond (( = (length lst) 1) (bubba-help lst))
      (else (bubbaS (bubba-help lst))))))

【问题讨论】:

  • 分享你迄今为止实现的内容,并指出你在试图进一步塑造它时遇到的困难。
  • Bubble Sorting in Scheme 的可能重复项
  • 我的问题与您所链接的不同,我不想将元素的数量作为参数传递。我想我应该把它加进去!

标签: scheme


【解决方案1】:

在我引用的possible-duplicate SO question 中使用bubble-up 和bubble-sort-aux 实现...

(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)))))))

(define (bubble-sort-aux N L)    
    (cond ((= N 1) (bubble-up L))   
          (else (bubble-sort-aux (- N 1) (bubble-up L)))))

...,这是简单的语法糖:

(define (bubbleH L) 
    (bubble-sort-aux (length L) L))

添加最后一点语法糖后,您应该得到您在问题中指定的内容:

(bubbleH '(5 10 9 8 7))
=> (5 7 8 9 10)

您可以在我保存并分享的repl.it session 中修改以上所有内容。

【讨论】:

    【解决方案2】:

    这是我自己的尾递归版本。

    就像你的bubbleH 过程一样,内部函数会冒出最大的数字。但它不会返回一个完整的列表,而是返回 2 个值:

    • 未排序的“剩余”列表
    • 冒泡的最大值

    如:

    > (bsort-inner '(5 1 4 2 8))
    '(5 2 4 1)
    8
    > (bsort-inner '(1 5 4 2 8))
    '(5 2 4 1)
    8
    > (bsort-inner '(4 8 2 5))
    '(5 2 4)
    8
    

    现在外循环只需要cons返回第二个值,然后迭代剩余的列表。

    代码:

    (define (bsort-inner lst)
      (let loop ((lst lst) (res null))
        (let ((ca1 (car lst)) (cd1 (cdr lst)))
          (if (null? cd1)
              (values res ca1)
              (let ((ca2 (car cd1)) (cd2 (cdr cd1)))
                (if (<= ca1 ca2)
                    (loop cd1 (cons ca1 res))
                    (loop (cons ca1 cd2) (cons ca2 res))))))))
    
    (define (bsort lst)
      (let loop ((lst lst) (res null))
        (if (null? lst)
            res
            (let-values (((ls mx) (bsort-inner lst)))
              (loop ls (cons mx res))))))
    

    对于递归版本,我更喜欢最小值在前面冒泡的版本:

    (define (bsort-inner lst)
      ; after one pass, smallest element is in front
      (let ((ca1 (car lst)) (cd1 (cdr lst)))
        (if (null? cd1)
            lst ; just one element => sorted
            (let ((cd (bsort-inner cd1))) ; cd = sorted tail
              (let ((ca2 (car cd)) (cd2 (cdr cd)))
                (if (<= ca1 ca2)
                    (cons ca1 cd)
                    (cons ca2 (cons ca1 cd2))))))))
    
    (define (bsort lst)
      (if (null? lst)
          null
          (let ((s (bsort-inner lst)))
            (cons (car s) (bsort (cdr s))))))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-18
      • 1970-01-01
      • 2010-11-24
      • 2021-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多