排序使用什么算法?


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)。
lunaryorn 2014年

让我们B先对其进行排序listA然后将其C初始为空列表。分割B为两个部分B1B2长度mmm+1m,比较newelt于第一元件B2。如果newelt就是延长A其使用权B1和替换BB2,否则扩大C其左侧具有B2和替换BB1。经过O(log n)这样的步骤后,什么也不会剩下B。然后A包含事物≤ newelt,事物和C那些> newelt,并串联产生扩展的排序列表。道歉不是很e-lisp喜欢语言。
2014年

Answers:


26

如果您已经安装了Emacs的源代码,你可以找到源代码sortM-x find-function

在那里您可以看到sort执行合并排序。它检查列表的长度,将列表分成两半,通过递归方式分别对“前”和“后”部分进行排序,然后合并两者。

至于您的实现是否会更快-请对其进行衡量!从理论上讲,它是更有效的(O(n)vs O(n log n)),但是sort具有用C语言编写的优势,因此结果可能会以任何一种方式出现。(当然,不要忘记对函数进行字节编译。)


@Malabarba记录下来,您测试了多少长度的长度?
T. Verron 2014年

8
测试1000次,将一个随机数插入1000个随机数的列表中(全部预先生成)。手动方法快了6倍。
马拉巴巴
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.