You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AutoLisp基于X坐标的坐标列表快速排序陷入无限循环问题排查求助

AutoLisp基于X坐标的坐标列表快速排序陷入无限循环问题排查求助

嘿,我看到你在用快速排序给坐标列表按X轴升序排序时陷入了无限循环,帮你梳理下代码里的几个关键问题,这些就是导致循环停不下来的核心原因:

1. qd:swap 函数完全没生效

AutoLisp是值传递的,你当前的swap函数只是交换了局部变量g和h的值,根本没碰原列表里的元素!这就导致分区操作时,元素位置完全没变化,每次递归的分区结果都一样,自然会无限循环下去。

你需要改成直接通过索引修改列表元素的方式,因为AutoLisp的列表是不可变的,修改后会生成新列表,所以swap要返回修改后的列表:

;; 先实现一个修改列表指定索引元素的工具函数
(defun setnth (idx val lst)
  (if (= idx 0)
    (cons val (cdr lst))
    (cons (car lst) (setnth (1- idx) val (cdr lst)))
  )
)

;; 修正后的swap函数,接收列表和两个索引,返回交换后的新列表
(defun qd:swap (sp idx1 idx2)
  (setq temp (nth idx1 sp))
  (setq sp (setnth idx1 (nth idx2) sp))
  (setq sp (setnth idx2 temp sp))
  sp
)

2. qd:partition 循环条件错误

你写的循环条件是 (< j (- (length sp) 2)),这是个固定值,完全没考虑当前分区的high参数!正确的循环范围应该是从low到high-1,也就是改成 (< j high),否则会漏掉分区内的部分元素,导致分区逻辑失效,递归无法收敛。

另外,i的初始值应该设为(1- low)而不是-1,因为low不一定是0,这样才能正确跟踪小于等于pivot的元素位置。修正后的partition函数:

(defun qd:partition (sp low high / pivot i j temp)
  (cond
    ((null sp) nil)
    (t
      (setq pivot (car (nth high sp)))
      (setq i (1- low))
      (setq j low)
      (while (< j high)
        (if (<= (car (nth j sp)) pivot)
          (progn
            (setq i (1+ i))
            (setq sp (qd:swap sp i j))
          )
        )
        (setq j (1+ j))
      )
      (setq sp (qd:swap sp (1+ i) high))
    )
  )
  (list sp (1+ i)) ; 返回修改后的列表和分区点索引
)

3. 递归时未传递修改后的列表

你的qd:quicksort_x函数没有返回值,也没有把partition修改后的列表传递给下一层递归,导致每次递归操作的都是原列表,分区永远没变化,自然无限循环。修正后的排序函数要接收并返回每次分区后的新列表:

(defun qd:quicksort_x (sp low high / part new-sp part-idx)
  (if (< low high)
    (progn
      (setq part (qd:partition sp low high))
      (setq new-sp (car part))
      (setq part-idx (cadr part))
      ;; 递归处理左右分区,传递更新后的列表
      (setq new-sp (qd:quicksort_x new-sp low (1- part-idx)))
      (setq new-sp (qd:quicksort_x new-sp (1+ part-idx) high))
      new-sp
    )
    sp ; 基线情况:分区只有一个元素,直接返回
  )
)

最后修正调用方式

现在排序函数会返回排序后的列表,调用时要接收这个返回值:

;; 你的坐标列表
(setq sp '((112040.0 -34649.7 0.0)
           (112004.0 -34641.7 0.0)
           (112134.0 -34649.7 0.0)
           (112098.0 -34641.7 0.0)
           (112000.0 -34773.7 0.0)
           (112000.0 -34881.7 0.0)
           (111946.0 -34801.7 0.0)))
(setq low 0)
(setq high (- (length sp) 1))
;; 输出排序结果
(princ (qd:quicksort_x sp low high))

把这些修改后,你的快速排序应该就能正常运行,按X坐标升序排列你的坐标列表了。

备注:内容来源于stack exchange,提问作者Gayathri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 07:08:03