Який алгоритм використовує сортування?


24

Мені потрібно додати одне ціле число до вже відсортованого списку таким чином, щоб воно було в потрібному місці. Перше моє враження було щось на кшталт

(sort (cons newelt list) #'<)

Однак, враховуючи, що listце вже відсортовано, дійсно потрібна лише одна вставка, що означає, що це рішення може бути жахливо непридатним, залежно від алгоритму, який використовується sort.

Отже, який алгоритм sortвикористовується?

Чи краще мені зробити щось подібне?

(let ((tail list))
  ;; The first element is never less-than
  (while (and tail (< newelt (cadr tail)))
    (setq tail (cdr tail)))
  (setcdr tail (cons newelt (cdr tail)))
  list)

1
Я б використовував двійкову купу (наприклад, heap.el ), якщо це була часта операція в моєму коді.
місячник

Нехай Bбуде початкова вже відсортовані listі Aі Cспочатку порожні списки. Поділ Bна дві частини B1, B2довжин mі mчи m+1та m, порівняйте neweltз першим елементом B2. Якщо neweltє продовжити Aйого права з B1і замінити Bз B2, інакше продовжити Cйого зліва з B2і замінити Bз B1. Після O(log n)таких кроків нічого не залишається B. Потім Aмістить речі ≤ newelt, і Cті > newelt, і конкатенація створює розширений відсортований список. Вибачення за не дуже e-lispлюблю мову.
jfbu

Відповіді:


26

Якщо у вас встановлений вихідний код Emacs, ви можете знайти вихідний код sortз M-x find-function.

Там ви бачите, що sortвиконує сортування злиття. Він перевіряє довжину списку, розбиває список навпіл, сортує "передню" та "задню" частини окремо за допомогою рекурсії, а потім об'єднує дві.

Що стосується того, чи буде ваша реалізація швидшою - вимірюйте це! Він є більш ефективним в теорії (O (n) проти O (n log n)), але sortмає перевагу в тому, що він пишеться в C, тому результат може йти в будь-який бік. (Звичайно, не забудьте пропустити-скласти свою функцію.)


@Malabarba Для запису, на якій шкалі довжин ви її тестували?
Т. Веррон

8
Випробувано 1000 разів, вставляючи випадкове число до списку 1000 випадкових чисел (усі попередньо створені). Ручний метод був у 6 разів швидшим.
Малабарба
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.