在合并排序中,我们在解决时分为两部分。为什么我们没有将它分成3个或更多部分?同样在我看到的许多分而治之的问题中,人们往往分为两部分。为什么不是3个或更多部分?它对解决方案/复杂性有什么影响?
答案 0 :(得分:3)
将问题分成3个或更多部分通常不方便,并且对算法的复杂性没有影响。它通常会对实际性能产生负面影响,因为更复杂的代码在实践中往往效率低于简单的简化代码。但情况并非总是如此。
有一些实用的D& C算法可以将问题分成两部分以上,因为这样做很有帮助。双枢轴快速排序就是一个例子。与常规快速排序相比,它往往更快(通过常数因素)。
答案 1 :(得分:1)
你可以。但这并不重要。将产生除以log_2
的复杂性(让我们来谈谈它)。
准确地说,您获得了log
,但它被推广到log_a
,因为复杂性分析中的常数因素无关紧要( Big-O-Notation < / strong>,Wikipedia)。而且您只需使用常数因子即可将log_b
转换为log_a(x) = log_b(x) * (1 / log_b(a))
:
2
在一个更具体的层面上,当你分成两半时,你会得到4
的常数因子。如果您现在拆分为2
,那么您将替换type Indexable<TKey, TValue> = { [index: TKey]: TValue }
,但实际上这只是一个常数因素变化,无论如何。
在使用并行或分布式编程时,实际上通常会分成两个以上的部分。
但除此之外,分而治之只是一种让人们更容易理解问题的技巧。你将一个更难的问题转化为更容易解决的小问题。
大多数时候分而治之的唯一好处就是它更容易理解。
答案 2 :(得分:1)
因为实现复杂性与时间复杂度之间存在权衡关系。
让我们通过一个例子来理解它,以及&#34;划分&#34;作品。假设我们有n
个元素,我们必须在其中执行一些算法。让我们看看线性和对数复杂性的差异。
比如说n~10^6
,那么数据集上的任何线性函数都需要大约10^6 * t
个时间单位,其中t
是处理一个数据点所花费的时间。对于分而治之的方法,这会减少到log(10^6) * t
个单位的时间。这取决于log的基数值,在分而治之算法中,它只是&#34;部分的数量&#34;我们将数据集划分为。
让我们看一下不同基数的日志数字。
base log 10^6 in base
2 20
3 12.6
4 10
等
因此,我们可以看到,分成更多部分实际上并没有减少那么多时间,因为对于数据集中的10 ^ 6个元素,你进行20次迭代或者12次或10次迭代,它没有&#39; t有所作为,但将它与10 ^ 6(O(n)-complex)进行比较,你会看到它。
现在,让我们看看如果我们分成3个部分并使用它会发生什么。它的实现比使用2个部分要复杂得多。我们无法实现任何重大的时间下降,但实施将需要我们始终保持计数器以了解我们正在使用的部分。在二进制分发中,我们可以轻松地使用布尔状态来维护此计数器,因为它很直观。
另外,正如其他人在答案中解释的那样,日志基础并没有改变时间复杂度的理论大O因子。
答案 3 :(得分:0)
您可以并且有时会实施。然而,对于big-O
符号,算法的最坏情况复杂度仍然相同。
显然,除法和同步算法本质上是递归的,所以你仍然会分解,直到问题处于一个微不足道的状态(基本情况 - 例如对两个数字进行排序)。你可能会很快到达这个案子,但要做更多的工作才能到达那里,在最坏的情况下,他们的表现会相同。
请参阅以下内容,因为此问题已在网上提出,人们提供了比我更好,更完整的答案: https://softwareengineering.stackexchange.com/questions/197107/divide-and-conquer-algorithms-why-not-split-in-more-parts-than-two
希望这有帮助!
同样来自上面我特别关注的链接:
&#34;另一方面,一些树形数据结构确实使用高 但是,分支因子(远大于3,通常为32或更多) 通常是出于其他原因。它提高了内存的利用率 层次结构:存储在RAM中的数据结构可以更好地利用缓存, 存储在磁盘上的数据结构需要较少的读取HDD-> RAM。&#34;