;; Бинарный поиск позиции для вставки (defun binary-search-pos (elem lst cmp) (labels ((binary-search (low high) (if (> low high) low ; Найдена позиция для вставки (let ((mid (floor (+ low high) 2))) (if (funcall cmp elem (nth mid lst)) (binary-search low (1- mid)) ; Ищем в левой половине (binary-search (1+ mid) high)))))) ; Ищем в правой половине (if (null lst) 0 ; Если список пуст, позиция для вставки - 0 (binary-search 0 (1- (length lst)))))) ;; Вставка элемента в список на заданную позицию (defun insert-at-pos (elem lst pos) (if (zerop pos) (cons elem lst) ; Вставляем в начало (if (null lst) (list elem) ; Если дошли до конца списка, а позиция не 0, вставляем в конец (для надежности) (cons (car lst) (insert-at-pos elem (cdr lst) (1- pos)))))) ; Рекурсивно двигаемся по списку ;; Основная функция сортировки бинарными включениями (defun binary-insertion-sort (lst cmp) (if (null lst) nil ; Пустой список уже отсортирован (let* ((first-elem (car lst)) (rest-sorted (binary-insertion-sort (cdr lst) cmp)) ; Рекурсивно сортируем остаток списка (pos (binary-search-pos first-elem rest-sorted cmp))) ; Находим позицию для вставки первого элемента (insert-at-pos first-elem rest-sorted pos)))) ; Вставляем первый элемент в отсортированный остаток ;; Примеры использования ;; Сортировка списка чисел по возрастанию (let ((numbers '(5 2 8 1 9 4))) (format t "Original list: ~a~%" numbers) (let ((sorted-numbers (binary-insertion-sort numbers #'<))) (format t "Sorted list: ~a~%" sorted-numbers))) ;; Сортировка списка строк по алфавиту (лексикографически) (let ((strings '("banana" "apple" "cherry" "date"))) (format t "Original list: ~a~%" strings) (let ((sorted-strings (binary-insertion-sort strings #'string<))) (format t "Sorted list: ~a~%" sorted-strings))) ;; Сортировка списка чисел по убыванию (изменили функцию сравнения) (let ((numbers '(5 2 8 1 9 4))) (format t "Original list: ~a~%" numbers) (let ((sorted-numbers (binary-insertion-sort numbers #'>))) (format t "Sorted list: ~a~%" sorted-numbers))) ;; Сортировка списка с использованием своей функции сравнения (по длине строки) (defun compare-string-length (str1 str2) (< (length str1) (length str2))) (let ((strings '("a" "bb" "ccc" "d"))) (format t "Original list: ~a~%" strings) (let ((sorted-strings (binary-insertion-sort strings #'compare-string-length))) (format t "Sorted list: ~a~%" sorted-strings))) ;; Пример с пустым списком (let ((empty-list '())) (format t "Original list: ~a~%" empty-list) (let ((sorted-list (binary-insertion-sort empty-list #'<))) (format t "Sorted list: ~a~%" sorted-list)))
Standard input is empty
Original list: (5 2 8 1 9 4) Sorted list: (1 2 4 5 8 9) Original list: (banana apple cherry date) Sorted list: (apple banana cherry date) Original list: (5 2 8 1 9 4) Sorted list: (9 8 5 4 2 1) Original list: (a bb ccc d) Sorted list: (d a bb ccc) Original list: NIL Sorted list: NIL
Warning: reserving address range 0x80000c0000...0x1fffffffffff that contains memory mappings. clisp might crash later! Memory dump: 0x8000000000 - 0x80000bffff 0x14b4b2c00000 - 0x14b4b2ee4fff 0x14b4b3015000 - 0x14b4b3039fff 0x14b4b303a000 - 0x14b4b31acfff 0x14b4b31ad000 - 0x14b4b31f5fff 0x14b4b31f6000 - 0x14b4b31f8fff 0x14b4b31f9000 - 0x14b4b31fbfff 0x14b4b31fc000 - 0x14b4b31fffff 0x14b4b3200000 - 0x14b4b3202fff 0x14b4b3203000 - 0x14b4b3401fff 0x14b4b3402000 - 0x14b4b3402fff 0x14b4b3403000 - 0x14b4b3403fff 0x14b4b3480000 - 0x14b4b348ffff 0x14b4b3490000 - 0x14b4b34c3fff 0x14b4b34c4000 - 0x14b4b35fafff 0x14b4b35fb000 - 0x14b4b35fbfff 0x14b4b35fc000 - 0x14b4b35fefff 0x14b4b35ff000 - 0x14b4b35fffff 0x14b4b3600000 - 0x14b4b3603fff 0x14b4b3604000 - 0x14b4b3803fff 0x14b4b3804000 - 0x14b4b3804fff 0x14b4b3805000 - 0x14b4b3805fff 0x14b4b393a000 - 0x14b4b393dfff 0x14b4b393e000 - 0x14b4b393efff 0x14b4b393f000 - 0x14b4b3940fff 0x14b4b3941000 - 0x14b4b3941fff 0x14b4b3942000 - 0x14b4b3942fff 0x14b4b3943000 - 0x14b4b3943fff 0x14b4b3944000 - 0x14b4b3951fff 0x14b4b3952000 - 0x14b4b395ffff 0x14b4b3960000 - 0x14b4b396cfff 0x14b4b396d000 - 0x14b4b3970fff 0x14b4b3971000 - 0x14b4b3971fff 0x14b4b3972000 - 0x14b4b3972fff 0x14b4b3973000 - 0x14b4b3978fff 0x14b4b3979000 - 0x14b4b397afff 0x14b4b397b000 - 0x14b4b397bfff 0x14b4b397c000 - 0x14b4b397cfff 0x14b4b397d000 - 0x14b4b397dfff 0x14b4b397e000 - 0x14b4b39abfff 0x14b4b39ac000 - 0x14b4b39bafff 0x14b4b39bb000 - 0x14b4b3a60fff 0x14b4b3a61000 - 0x14b4b3af7fff 0x14b4b3af8000 - 0x14b4b3af8fff 0x14b4b3af9000 - 0x14b4b3af9fff 0x14b4b3afa000 - 0x14b4b3b0dfff 0x14b4b3b0e000 - 0x14b4b3b35fff 0x14b4b3b36000 - 0x14b4b3b3ffff 0x14b4b3b40000 - 0x14b4b3b41fff 0x14b4b3b42000 - 0x14b4b3b47fff 0x14b4b3b48000 - 0x14b4b3b4afff 0x14b4b3b4d000 - 0x14b4b3b4dfff 0x14b4b3b4e000 - 0x14b4b3b4efff 0x14b4b3b4f000 - 0x14b4b3b4ffff 0x14b4b3b50000 - 0x14b4b3b50fff 0x14b4b3b51000 - 0x14b4b3b51fff 0x14b4b3b52000 - 0x14b4b3b58fff 0x14b4b3b59000 - 0x14b4b3b5bfff 0x14b4b3b5c000 - 0x14b4b3b5cfff 0x14b4b3b5d000 - 0x14b4b3b7dfff 0x14b4b3b7e000 - 0x14b4b3b85fff 0x14b4b3b86000 - 0x14b4b3b86fff 0x14b4b3b87000 - 0x14b4b3b87fff 0x14b4b3b88000 - 0x14b4b3b88fff 0x5641e890e000 - 0x5641e89fefff 0x5641e89ff000 - 0x5641e8b08fff 0x5641e8b09000 - 0x5641e8b68fff 0x5641e8b6a000 - 0x5641e8b98fff 0x5641e8b99000 - 0x5641e8bc9fff 0x5641e8bca000 - 0x5641e8bcdfff 0x5641e9002000 - 0x5641e9022fff 0x7ffcc4081000 - 0x7ffcc40a1fff 0x7ffcc40cc000 - 0x7ffcc40cffff 0x7ffcc40d0000 - 0x7ffcc40d1fff