fork download
  1. ;; Бинарный поиск позиции для вставки
  2. (defun binary-search-pos (elem lst cmp)
  3. (labels ((binary-search (low high)
  4. (if (> low high)
  5. low ; Найдена позиция для вставки
  6. (let ((mid (floor (+ low high) 2)))
  7. (if (funcall cmp elem (nth mid lst))
  8. (binary-search low (1- mid)) ; Ищем в левой половине
  9. (binary-search (1+ mid) high)))))) ; Ищем в правой половине
  10. (if (null lst)
  11. 0 ; Если список пуст, позиция для вставки - 0
  12. (binary-search 0 (1- (length lst))))))
  13.  
  14. ;; Вставка элемента в список на заданную позицию
  15. (defun insert-at-pos (elem lst pos)
  16. (if (zerop pos)
  17. (cons elem lst) ; Вставляем в начало
  18. (if (null lst)
  19. (list elem) ; Если дошли до конца списка, а позиция не 0, вставляем в конец (для надежности)
  20. (cons (car lst) (insert-at-pos elem (cdr lst) (1- pos)))))) ; Рекурсивно двигаемся по списку
  21.  
  22. ;; Основная функция сортировки бинарными включениями
  23. (defun binary-insertion-sort (lst cmp)
  24. (if (null lst)
  25. nil ; Пустой список уже отсортирован
  26. (let* ((first-elem (car lst))
  27. (rest-sorted (binary-insertion-sort (cdr lst) cmp)) ; Рекурсивно сортируем остаток списка
  28. (pos (binary-search-pos first-elem rest-sorted cmp))) ; Находим позицию для вставки первого элемента
  29. (insert-at-pos first-elem rest-sorted pos)))) ; Вставляем первый элемент в отсортированный остаток
  30.  
  31. ;; Примеры использования
  32. ;; Сортировка списка чисел по возрастанию
  33. (let ((numbers '(5 2 8 1 9 4)))
  34. (format t "Original list: ~a~%" numbers)
  35. (let ((sorted-numbers (binary-insertion-sort numbers #'<)))
  36. (format t "Sorted list: ~a~%" sorted-numbers)))
  37.  
  38. ;; Сортировка списка строк по алфавиту (лексикографически)
  39. (let ((strings '("banana" "apple" "cherry" "date")))
  40. (format t "Original list: ~a~%" strings)
  41. (let ((sorted-strings (binary-insertion-sort strings #'string<)))
  42. (format t "Sorted list: ~a~%" sorted-strings)))
  43.  
  44. ;; Сортировка списка чисел по убыванию (изменили функцию сравнения)
  45. (let ((numbers '(5 2 8 1 9 4)))
  46. (format t "Original list: ~a~%" numbers)
  47. (let ((sorted-numbers (binary-insertion-sort numbers #'>)))
  48. (format t "Sorted list: ~a~%" sorted-numbers)))
  49.  
  50. ;; Сортировка списка с использованием своей функции сравнения (по длине строки)
  51. (defun compare-string-length (str1 str2)
  52. (< (length str1) (length str2)))
  53.  
  54. (let ((strings '("a" "bb" "ccc" "d")))
  55. (format t "Original list: ~a~%" strings)
  56. (let ((sorted-strings (binary-insertion-sort strings #'compare-string-length)))
  57. (format t "Sorted list: ~a~%" sorted-strings)))
  58.  
  59. ;; Пример с пустым списком
  60. (let ((empty-list '()))
  61. (format t "Original list: ~a~%" empty-list)
  62. (let ((sorted-list (binary-insertion-sort empty-list #'<)))
  63. (format t "Sorted list: ~a~%" sorted-list)))
Success #stdin #stdout #stderr 0.02s 9436KB
stdin
Standard input is empty
stdout
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
stderr
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