我尝试使用所有常规操作(merge,delete-min等)实现“配对堆”,然后我被要求编写一个函数,该函数将使用我新构造的堆实现对列表进行排序。不幸的是,似乎有些问题......
以下是相关代码:
(define (heap-merge h1 h2)
(cond ((heap-empty? h1) h2)
((heap-empty? h2) h1)
(else (let ((min1 (heap-get-min h1))
(min2 (heap-get-min h2)))
(if ((heap-get-less h1) min1 min2)
(make-pairing-heap (heap-get-less h1) min1 (cons h2 (heap-get-subheaps h1)))
(make-pairing-heap (heap-get-less h1) min2 (cons h1 (heap-get-subheaps h2))))))))
(define (heap-insert element h)
(heap-merge (make-pairing-heap (heap-get-less h) element '())
h))
(define (heap-delete-min h)
(define (merge-in-pairs less? subheaps)
(cond
((null? subheaps) (make-heap less?))
((null? (cdr subheaps)) (car subheaps))
(else (heap-merge (heap-merge (car subheaps) (cadr subheaps))
(merge-in-pairs less? (cddr subheaps))))))
(if (heap-empty? h) (error "expected pairing-heap for first argument, got an empty heap ")
(merge-in-pairs (heap-get-less h) (heap-get-subheaps h))))
(define (heapsort l less?)
(let aux ((h (accumulate heap-insert (make-heap less?) l)))
(if (not (heap-empty? h))
(cons (heap-get-min h)
(aux (heap-delete-min h))))))
这些是一些可以帮助您理解代码的选择器:
(define (make-pairing-heap less? min subheaps)
(cons less? (cons min subheaps)))
(define (make-heap less?)
(cons less? '()))
(define (heap-get-less h)
(car h))
(define (heap-empty? h)
(if (null? (cdr h)) #t #f))
现在让我们解决问题:当我运行'heapsort'时,它返回带有“void”的排序列表,如你所见:
> (heapsort (list 1 2 3) <)
(1 2 3 . #<void>)
..我如何修复它?
此致 Superguay
答案 0 :(得分:2)
由于这是作业,我会告诉你我用来查找错误的过程。如果您仍然被卡住,请告诉我。
老实说,这是一个太多的代码,无法在Stack Overflow问题中进行深入分析。所以我必须使用输出中的线索。具体来说,您有一个包含空格的列表。它最后是一个不合适的列表。这意味着两件事:
if
- else
分支将返回void - 或者(2)用display
结束你的函数,返回无效。cons
。您可能本来打算继续进行,或者您可能想用'()代替正确地结束列表。所以:第一步是搜索代码以查找cons
的所有用途。你的选择器看起来很好。这使得heap-merge
中的两个分支和cons
中的heapsort
分开。对cons
的所有三次调用都使用函数来获取cdr
。
所以:下一步是查看heap-get-subheaps
和aux
,看看是否有一个代码路径没有返回值。也许你错误地留下了一些调试语句。或者你可能有if
只有真正的分支,你忘了假分支。
*注意:大多数方案都有这么少的调试功能,无论如何,启发式扫描是最好的选择。这是一项后天的技能。