(defun heapify-down (heap-id
index)
(if
(is-leaf heap-id
index)
nil
(let ((left (left-child index))
(right (right-child index))
(heap-array (heap-actual-heap heap-id)))
(cond
((null (aref heap-array
left))
(if (= (find-largest heap-id
index
right)
index)
(swap heap-array
index
right))
nil)
((null (aref heap-array
right))
(if (= (find-largest heap-id
index
left)
index)
(swap heap-array
index
left))
nil)
((and (= (find-largest heap-id
index
left)
left)
(= (find-largest heap-id
index
right)
right))
nil)
(t
(let (new-index (find-smallest heap-id
left
right))
(swap heap-array
index
new-index)
(heapify-down heap-id
new-index)))))))
所以我只是想知道我的格式化方式是否正确。我查看了一些有关该主题的在线指南,但我不确定我是否以最好的方式做这件事,特别是因为我的老师对该主题非常严格。
一行中没有单括号或其他各种常见问题,并且看起来表格对齐正确,因此已经可读;我认为你倾向于添加大量换行符,没有什么特殊原因(例如,在 if 之后?):Common Lisp 通常在垂直方向上更紧凑一些。另请注意,对于
if
有一个为零的分支的情况,您有宏,即 when
和 unless
。
我将重写它如下,并使用一些小的辅助函数,希望能让事情变得更清晰。您也应该尝试添加评论。
(defpackage :stack-overflow (:use :cl))
(in-package :stack-overflow)
(defun heapify-down (heap-id index)
(unless (is-leaf heap-id index)
(let ((left (left-child index))
(right (right-child index))
(heap-array (heap-actual-heap heap-id)))
(flet ((get-node (index) (aref heap-array index))
(swap-with (other) (swap heap-array index other))
(find-largest (node) (find-largest heap-id index node)))
(cond
;; no left node => swap with right
((null (get-node left))
(when (= index (find-largest right))
(swap-with right)))
;; no right node => swap with left
((null (aref heap-array right))
(when (= index (find-largest left))
(swap-with left)))
;; both left and right are already sorted
((and (= left (find-largest left))
(= right (find-largest right)))
nil)
;; add a new child and heapify down
(t (let (new-index (find-smallest heap-id left right))
(swap-with new-index)
(heapify-down heap-id new-index))))))))