2012-01-25 45 views
3

为了使长话短说:我的算法类是太容易了,所以我的挑战我自己做的Common Lisp中所有任务(几个,具体原因)。我进入学习lisp的第一天,我遇到了一个障碍。Common Lisp的归并排序打破

的任务是排序创建一个合并,当你得到一个任意子集长度(Timsort)转换为插入。插入部分完美地工作,但合并的分割部分仅在程序必须分割两次时才起作用。我知道这与列表中的列表工作方式有关,我只是太新而无法查明问题。

我觉得无论是打一个无限循环......我不知道,因为当我与调试语句运行它,它们不会在设定有太多的元素打印。

我不是在这里乞讨具体的答案或有人给我写的代码。也许向正确方向的解释或点可能会有很大帮助!

感谢先进!

我的代码:

;; Insertion sort method call (returns sorted list) 
(defun insert-sort (lst) ...) 

;; Merge sort method call 
(defun merge-sort (lst) 
    (print 'Merge) 
    (print lst) 
    (if (< (length lst) 7) ; Check to see if list is small enough to insert sort 
     (insert-sort lst) ; Do so 
     (progn ; else 
     (setf b (merge-split lst)) ; Split the list, store into b 
     (setf (car b) (merge-sort (car b))) ; Merge sort on first half 
     ;; --- I think it's happening here --- 
     (setf (cdr b) (merge-sort (cdr b))) ; Merge sort on second half 
     (merge 'list (car b) (cdr b) #'<)))) ; Merge the two lists together (using API) 

;; Split a list into two parts 
(defun merge-split (lst) 
    (progn 
    (setf b lst) ; Set b to first index 
    (setf a (cdr lst)) ; Set a to the rest of the list 
    (loop while a do ; Loop while a != null 
      (setf a (cdr a)) ; Make a equal next list node 
      (if a ; If it still exists 
       (progn 
       (setf a (cdr a)) ; Inc a again 
       (setf b (cdr b))))) ; Also inc b (b should always be half of a) 
    (setf a (cdr b)) ; Set a to the list after b 
    (setf (cdr b) NIL) ; Delete link after b 
    (cons lst a))) ; Return in a cons 

注:这是我写的代码,没有下车的互联网......你可能会说,虽然哈哈

+0

一旦你得到它的工作,把它交给[代码审查(http://codereview.stackexchange.com/)样式的反馈。 – Inaimathi

回答

4

你被动态作用域咬伤变量。第一次调用SETF设置a,b隐式创建全局的,动态范围的变量。用LET来声明它们。 LET允许您包含要执行的表达式列表,就像PROGN一样,所以我的提示是您可以通过将2个PROGN改为LET来解决此问题。让我知道如果你需要更多的东西来解决这个问题。

+0

啊!谢谢!我从来不知道什么是最适当的方式来实例化变量呢。我会就这个问题做更多的研究。 再次感谢! –

+0

它的工作!现在我明白每个命令如何启动变量这样一个简单的修复。 谢谢吨! –