编写用于合并排序的LISP递归函数有困难

编写用于合并排序的LISP递归函数有困难,lisp,common-lisp,Lisp,Common Lisp,您好,我有一个问题,我解决起来有点困难,见下文 使用函数SPLIT-LIST和MERGE-LIST定义递归 Lisp函数MSORT,如果L是实数列表,则(MSORT L)是由L元素按升序组成的列表。在MSORT的定义中,您可以调用SPLIT-LIST, MSORT本身、合并列表、CAR、CDR、CADR和ENDP,但不应调用任何 其他功能。请确保使用LET或LET*,以便MSORT只调用SPLIT-LIST一次 到目前为止,我能够正确地编写SPLIT-LIST和MERGE-LIST函数,但是对于

您好,我有一个问题,我解决起来有点困难,见下文

使用函数SPLIT-LIST和MERGE-LIST定义递归 Lisp函数MSORT,如果L是实数列表,则(MSORT L)是由L元素按升序组成的列表。在MSORT的定义中,您可以调用SPLIT-LIST, MSORT本身、合并列表、CAR、CDR、CADR和ENDP,但不应调用任何 其他功能。请确保使用LET或LET*,以便MSORT只调用SPLIT-LIST一次

到目前为止,我能够正确地编写SPLIT-LIST和MERGE-LIST函数,但是对于M-SORT,我在编写函数时遇到了困难。到目前为止,请参见以下所有三个定义。如果您能按照问题中的指导原则正确编写MSORT函数,我们将不胜感激

(defun SPLIT-LIST (L)
  (if (endp L)
      '(nil nil)
    (let ((X (split-list (cdr L))))
      (list  (cons (car L)(cadr X)) (car X) ))))

(defun MERGE-LISTS (L1 L2)
  (cond
   ((and(endp L1 )(endp L2)) nil )
   ((endp L1) (cons (CAR L2) (MERGE-LISTS nil (CDR L2))))
   ((endp L2) (cons (CAR L1) (MERGE-LISTS (CDR L1) NIL)))
   ((< (CAR L1) (CAR L2)) (cons (CAR L1) (MERGE-LISTS (CDR L1) L2  )))  
   ((>= (CAR L1) (CAR L2)) (cons (CAR L2) (MERGE-LISTS L1 (CDR L2))  ))))

(defun MSORT (L)
  (cond ((endp L ) nil)
        ( (equal (Length L) 1) L)
        (T
         (let* (
                (S (SPLIT-LIST L ))
                (L1 (CAR S))
                (L2 (CADR S))
                (X (MSORT (cdr L1)))
                (Y (MSORT (cdr L2)))


                )
           (MERGE-LISTS 
            (if (and (numberp (car L1)) (numberp (car X))(<=  (car L1 ) (car X)))  
                (list (car L1) (car X))
              (list (car X) (car L1) )
              ) 

            (Cons (car L2) Y))

           )))
  )
(定义拆分列表(L)
(如有)
"(无无)
(let((X(拆分列表(cdr L)))
(列表(cons(左车)(cadr X)(X车)))
(删除合并列表(L1 L2)
(续)
((和(endp L1)(endp L2))无)
((endp L1)(cons(CAR L2)(合并列表零(CDR L2)))
((endp L2)(cons(CAR L1)(合并列表(CDR L1)NIL)))
((<(一级车厢)(二级车厢))(一级车厢)(合并列表(一级车厢)二级车厢)))
((>=(汽车L1)(汽车L2))(反对者(汽车L2)(合并列表L1(CDR L2)))
(左)
(续)(完左)无)
((相等(长度L)1)L)
(T
(让我们*(
(S(拆分名单L))
(L1(车辆S))
(L2(CADR S))
(X(MSORT(cdr L1)))
(Y(MSORT(cdr L2)))
)
(合并列表)

(如果(和(numberp(car L1))(numberp(car X))(您将其过度复杂化。您不需要对
SPLIT-LIST
返回的子列表的
CDR
排序,只需对整个列表排序,然后合并它们即可

(defun MSORT (L)
  (cond ((endp L) nil)
        ((endp (cdr L)) L)
        (t
         (let* ((S (SPLIT-LIST L ))
                (L1 (car S))
                (L2 (cadr S))
                (X (MSORT L1))
                (Y (MSORT L2)))
           (MERGE-LISTS X Y)))))

为什么只在
L1
L2
的cdr上调用
MSORT
?将它们全部排序,然后合并结果。我假设这里的要点是自己实现这些,但请注意,Common Lisp提供了一个可以处理列表(和向量!)的方法。(当然,它还提供了一个排序函数,但这不一定是合并排序。)非常感谢Barmar。你是一个救生员。是的,重点是自己编写这个函数。我不知道为什么我把它复杂化了。你给出的东西非常有意义。