O(n log n)vs O(n) - 时间复杂度的实际差异

时间:2014-01-31 20:43:31

标签: algorithm big-o time-complexity

n log n > n - 但这就像pseudo-linear关系一样。如果n=1 billion,请记录n~30;

所以n log n将是30 billion30 X nn的顺序。 我想知道n log n and n之间的时间复杂度差异在现实生活中是否显着。

例如:使用quickselect算法,quick select查找未排序数组中的第k个元素为O(n)

如果我对数组进行排序并找到第k个元素,则为O(n log n)。要使用1 trillion元素对数组进行排序,如果60 timesquicksort,则index it会慢一些。

5 个答案:

答案 0 :(得分:53)

Big-O表示法的主要目的是让你像你在帖子中那样进行估算,并自己决定是否花费你的精力编写一个通常更高级的算法是值得你额外的CPU周期将采用该代码改进购买。根据具体情况,即使您的数据集相对较小,您也可能得到不同的答案:

  • 如果您在移动设备上运行,并且算法占执行时间的很大一部分,那么减少使用CPU会延长电池续航时间
  • 如果您在一个全有或全无竞争的环境中运行,例如高频交易系统,微优化可以区分赚钱和亏钱
  • 当您的分析显示所讨论的算法在服务器环境中占据主导地位时,切换到更快的算法可能会提高所有客户的性能。

Big-O符号隐藏的另一件事是常数倍增因子。例如,Quick Select具有非常合理的乘数,因此在非常大的数据集上使用它所节省的时间非常值得实现它。

您需要记住的另一件事是空间复杂性。通常,具有O(N*Log N)时间复杂度的算法将具有O(Log N)空间复杂度。这可能会给极大的数据集带来问题,例如,当递归函数在具有有限堆栈容量的系统上运行时。

答案 1 :(得分:27)

取决于。

我在亚马逊工作,有一种方法,就是在列表上进行线性搜索。我们可以使用Hashtable并在O(1)中查找与O(n)相比。

我建议进行更改,但未获批准。因为输入很小,所以不会产生很大的差异。

但是,如果输入很大,那么它会产生影响。

在另一家公司,数据/输入量巨大,使用树,与List相比产生了巨大的差异。所以它取决于应用程序的数据和架构。

了解您的选择以及如何进行优化总是很好的。

答案 2 :(得分:10)

有些时候你会使用数十亿个元素(以及更多),这些差异肯定会很大。

还有一些时候你将使用不到一千个元素,在这种情况下,差异可能不会那么显着。

如果您对数据的外观有一个不错的认识,那么您应该从一开始就选择哪一个,但是O(n)和O(n log n)之间的差异足够小以至于它是可能最好从最简单的一个开始,对它进行基准测试,只有在你发现速度过慢时才尝试改进它。

然而,请注意,对于任何给定的n值,O(n)实际上可能比O(n log n)慢(特别是,但不一定,对于n的小值),因为涉及的常数因素很大-O忽略了那些(它只考虑当n趋于无穷大时会发生什么),所以,如果你纯粹看时间复杂度,你认为可能改进的东西实际上可能会使事情变慢。

答案 3 :(得分:2)

达斯维达是对的。它总是取决于。记住复杂性是渐近的,最坏情况(通常)并且常数被丢弃也很重要。其中每一个都很重要。

所以你可以有两个算法,其中一个是O(n),其中一个是O(nlogn),对于宇宙中及其以外的每个原子数的值(到n的某个有限值) ),O(nlogn)算法优于O(n)算法。这可能是因为低阶项是主导的,或者可能是因为在一般情况下,O(nlogn)算法实际上是O(n),或者因为实际步数是5,000,000n对3nlogn。

答案 4 :(得分:0)

PriorityQueue使用Collections.sort()对每次添加的元素进行排序。它将对单个go中的所有元素进行排序。但是如果你有一个问题,你想尽快获得最大的元素,另一方面使用PriorityQueue,如果你需要执行一些计算,但需要对元素进行排序,那么使用带有Collections.Sort的ArrayList是最好的