【发布时间】:2013-08-30 09:02:25
【问题描述】:
该函数仅适用于正数。有时适用于负数,但大多数时候显示此错误“值 -1 不是 UNSIGNED-BYTE 类型”。
(defun OrdRapido (lista inf sup)
(let ((pivote (nth sup lista)) (i (1- inf)) (j sup) (aux))
(unless (>= inf sup)
(loop (when (>= i j) (return))
(loop (setf i (1+ i)) (when (>= (nth i lista) pivote) (return)))
(loop (setf j (1- j)) (when (<= (nth j lista) pivote) (return)))
(when (< i j)
(setf aux (nth i lista))
(setf (nth i lista) (nth j lista))
(setf (nth j lista) aux)))
(setf aux (nth i lista))
(setf (nth i lista) (nth sup lista))
(setf (nth sup lista) aux)
(OrdRapido lista inf (1- i))
(OrdRapido lista (1+ i) sup))
lista))
例如:
(setq lista2 '(-5 3 7 6 2 1 -4 100 5 80 96 14 2 3 1 0 0 789 -1 3))
(OrdRapido lista2 0 (1- (length lista2)))
CL-USER>
(-5 3 7 6 2 1 -4 100 5 80 96 14 2 3 1 0 0 789 -1 3)
CL-USER>
(-5 -4 -1 0 0 1 1 2 2 3 3 3 5 6 7 14 80 96 100 789)
但是这个不行,我只加-到80
'(-5 3 7 6 2 1 -4 100 5 -80 96 14 2 3 1 0 0 789 -1 3)
谢谢
修正版(随机添加),我知道有更好的方法,这只是教授留下的练习
(defun OrdRapido (lista inf sup)
(let ((pivote (nth (random (1+ sup)) lista)) (i inf) (j sup) (aux))
(unless (>= inf sup)
(loop (when (> i j) (return))
(loop (when (<= (nth i lista) pivote) (return)) (setf i (1+ i)))
(loop (when (>= (nth j lista) pivote) (return)) (setf j (1- j)))
(when (<= i j)
(setf aux (nth i lista))
(setf (nth i lista) (nth j lista))
(setf (nth j lista) aux)
(setf i (1+ i))
(setf j (1- j))))
(OrdRapido lista inf j)
(OrdRapido lista i sup))
lista))
【问题讨论】:
-
和负数无关,试试
'(2 1)。 -
答案中显示的这些“其他方式”(即递归扁平树变体)是否“更好”,值得商榷。您的代码看起来像真正的快速排序,就地分区。您可以通过随机选择枢轴来改进它,以防止有序输入的急剧下降。
-
感谢您的信息,我刚刚添加了随机枢轴 :)
-
无论这是否是“真正的”快速排序...您的代码具有灾难性的渐近复杂性。您应该重写它以使用数组,或者使用列表完全不同。你在这里所做的超出了二次时间。
-
基本上,可以这样想:如果您使用
nth并带有一个常量小于,例如 8,那么您很好。但如果不是,你做事的方式是错误的。但最好不要使用它/仅用于调试。
标签: types lisp common-lisp quicksort negative-number