(1 2 3 . #)- 堆排序
我尝试用所有常规操作(合并、删除最小等)实现一个“配对堆”,然后我被要求编写一个函数,使用我新构建的堆实现对列表进行排序。不幸的是,似乎有些地方出了问题......
这是相关的代码:
(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>)
..我该如何解决它?
问候, 超级守护者
I tried to implement a "pairing heap" with all the regular operations (merge, delete-min etc.), then I've been requested to write a function that would sort a list using my newly constructed heap implementation. Unfortunately it seems that someting goes wrong...
Here's the relevant code:
(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))))))
And these are some selectors that may help you to understand the code:
(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))
Now lets get to the problem: When i run 'heapsort' it returns the sorted list with "void", as you can see:
> (heapsort (list 1 2 3) <)
(1 2 3 . #<void>)
..HOW CAN I FIX IT?
Regards,
Superguay
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于这是作业,我将告诉您我用来查找错误的过程。如果您仍然卡住,请告诉我。
老实说,在 Stack Overflow 问题中,代码太多,无法深入分析*。所以我必须使用输出中的线索。具体来说,您有一个其中包含空白的列表。它位于最后,在不正确的列表中。这意味着两件事:
if
-else
分支将返回 void - 或者 (2) 以 < 结束你的函数code>display,返回 void。cons
。您可能打算继续 consing,或者您可能打算在 '() 上进行 cons,而不是正确地结束列表。所以:第一步是在代码中搜索
cons
的所有用途。你的选择器看起来不错。这样就留下了heap-merge
中的两个分支和heapsort
中的cons
。对cons
的所有三个调用都使用函数来获取其cdr
。因此:下一步是查看 heap-get-subheaps 和 aux 来查看其中一个是否具有不返回值的代码路径。也许您错误地留下了一些调试语句。或者也许您有一个只有 true 分支的
if
,而您忘记了 false 分支。*注意:大多数方案的调试功能很少,因此启发式方法无论如何都是您的最佳选择。这是一项后天获得的技能。
Since this is homework, I'll tell you the process I used to find the bug. Let me know if you're still stuck.
Honestly, this is too much code to analyse* in-depth in a Stack Overflow question. So I have to use clues from the output. Specifically, you have a list with a void in it. And it's at the end, in an improper list. That means two things:
if
with only one branch--theelse
branch will return void--or (2) ending your function with adisplay
, which returns void.cons
. You might have meant to keep consing or maybe you meant to cons on '() instead to end the list properly.So: first step is to search the code for all uses of
cons
. Your selectors look fine. That leaves the two branches inheap-merge
and thecons
inheapsort
. All three calls tocons
use functions to get theircdr
.So: next step is to look at
heap-get-subheaps
andaux
to see if either one has a code path that doesn't return a value. Maybe you have some debugging statements left in by mistake. Or maybe you have anif
that only has the true branch and you forgot the false branch.*Note: Most Schemes have so few debugging features that heuristics are your best bet anyway. It's an acquired skill.