シェルソート習作
(setq h 3) (defun make-new-list (&optional (list) (num) (n 0) (t-list nil)) (cond ((not (cdr list)) (if (= num n) (append t-list (list (car list))) t-list)) ((= num n) (make-new-list (cdr list) (+ num h) (1+ n) (append t-list (list (car list))))) (t (make-new-list (cdr list) num (1+ n) t-list)))) (defun replace-list (&optional (list) (num) (t-list) (n 0)) (if (= num n) (progn (setf (car list) (car t-list)) (if (cdr t-list) (setf (cdr list) (replace-list (cdr list) (+ num h) (cdr t-list) (1+ n))))) (setf (cdr list) (replace-list (cdr list) num t-list (1+ n)))) list) (defun do-simple-insert (list num) (if (not list) (setf list (list num)) (if (< (car list) num) (setf (cdr list) (do-simple-insert (cdr list) num)) (setf list (cons num list)))) list) (defun simple-insert-sort (list) (let ((ret-list)) (dolist (x list ret-list) (setf ret-list (do-simple-insert ret-list x))))) (defun shell-sort (list) (if (not (= h 1)) (progn (dotimes (x h ret-list) (setf list (replace-list list x (simple-insert-sort (make-new-list list x))))) (setf h (round (/ h 2))) (shell-sort list)) (simple-insert-sort list))) ; 結果 ; * (shell-sort '(3 1 5 2 6 4)) ; ; (1 2 3 4 5 6) ; *
微妙に寝不足なので、これで手一杯。大枠は間違っていなくとも、随分回り道をしてる予感がぷんぷんする。
備忘録として書いておくと、make-new-listは、num+(hの倍数)の位置の要素を取り出して、新たなリストを作成。replace-listは、num+(hの倍数)の位置の要素を、t-listのcarにそれぞれ置き換える。この動作は、t-listがなくなるまで続く。あとは単純挿入ソートと同じかな。