sortはどのアルゴリズムを使用しますか?


24

既にソートされているリストに単一の整数を追加して、適切な場所に配置する必要があります。私の最初の考えは次のようなものでした

(sort (cons newelt list) #'<)

ただし、それlistが既にソートされている場合、実際に必要な挿入は1つだけです。つまり、で使用されるアルゴリズムによっては、このソリューションは恐ろしく不適切になる可能性があります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)を使用します(コードで頻繁に行われる場合)。
lunaryorn 14年

してみましょうB最初のことがすでにソートlistAし、C最初は空のリスト。スプリットB二つの部分にB1B2長さm及びmあるいはm+1とはm、比較neweltの最初の要素にB2。もしneweltある拡張Aとその右にB1して交換BしてB2拡張する他、Cとその左にB2して交換BしてB1。そのO(log n)ようなステップの後、には何も残されませんB。次にA、things ≤ neweltCthose が含まれ、> newelt連結によって拡張ソートリストが生成されます。e-lisp言語があまり好きではないことをおologiesびします。
jfbu 14年

回答:


26

あなたがEmacsのソースコードがインストールされている場合は、ソースコードを見つけることができるsortとしM-x find-function

sortマージソートを実行することがわかります。リストの長さをチェックし、リストを半分に分割し、再帰によって「前」と「後」の部分を別々にソートしてから、2つをマージします。

実装が高速になるかどうかを測定します。理論上はより効率的ですが(O(n)vs O(n log n))、sortCで記述されるという利点があるため、結果はどちらの方向にも進む可能性があります。(もちろん、関数をバイトコンパイルすることを忘れないでください。)


@Malabarba記録のために、どの長さのスケールでテストしましたか?
T.バーロン14年

8
1000回のテストを行い、1000個の乱数のリストに乱数を挿入しました(すべて事前生成)。手動の方法は6倍高速でした。
マラバルバ14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.