作为本科生,我学习了O(n log n)的排序算法以及证明当我们只能比较两个数字时,在通用情况下我们无法做得更好。这是针对计算模型中的随机访问内存的。
我想知道是否存在这样的理论下界,适用于函数式(引用透明)程序。假设每次Beta规约都算一步,每次比较也算一步。
作为本科生,我学习了O(n log n)的排序算法以及证明当我们只能比较两个数字时,在通用情况下我们无法做得更好。这是针对计算模型中的随机访问内存的。
我想知道是否存在这样的理论下界,适用于函数式(引用透明)程序。假设每次Beta规约都算一步,每次比较也算一步。
我认为现代函数式编程实现(至少是Clojure,因为那是我唯一了解的)确实具有不可变内存,但这并不意味着更改列表等会导致整个原始列表的复制。因此,我不相信使用命令式或函数式习惯语实现排序算法之间存在数量级的计算差异。
为了说明这可能的工作方式,请考虑来自Clojure参考资料的此代码片段:http://clojure-doc.org/articles/tutorials/introduction.html
在Clojure中,所有标量和核心数据结构都是这样的。它们是值。它们是不可变的。{:name "John" :hit-points 200 :super-power :resourcefulness}
是一个值。如果你想“改变”约翰的命中点数,你并没有真正改变任何东西,而是只是创造了一个全新的哈希映射值。我不知道函数式编程的完整历史,但在我看来,函数式语言的不可变性特征基本上是将共享内存的复杂性抽象出来。
虽然这很酷,但如果没有语言管理的共享数据结构作为整个机制的基础,对于许多用例而言,它将变得难以实际应用。
log n
的开销在纯代码中模拟可变内存,并且有些问题你无法做得比这更好(更多细节请见此:https://dev59.com/sXI-5IYBdhLWcg3wKE-x#1990580),这就是为什么算法的时间复杂度在函数式编程风格下可能与通常情况不同的原因。 - Ben