分而治之,因为数学支持它!
考虑一些分而治之的算法:
1) 二分搜索:该算法每次将您的输入空间减少一半。很明显,这比线性搜索要好,因为我们会避免查看很多元素。
但是好到什么程度呢?我们得到了重复(注意:这是最坏情况分析的重复):
T(n) = T(n/2) + O(1)
数学暗示T(n) = Theta(log n)。因此,这比线性搜索要好得多。
2) 合并排序: 这里我们分成(几乎)相等的两半,对两半进行排序然后合并。为什么这应该比二次方更好?这是重复:
T(n) = 2T(n/2) + O(n)
T(n) = Theta(n log n) 可以用数学方法证明(比如使用主定理)。因此 T(n) 渐近优于二次。
观察到 naive 快速排序最终给了我们最坏情况下的重复
T(n) = T(n-1) + O(n)
从数学上讲,它是二次的,在最坏的情况下,并不比冒泡排序好(渐近地说)。但是,我们可以证明,在平均情况下,快速排序是 O(n log n)。
3 选择算法:这是一种分治算法,用于查找第 k^th 大元素。这种算法是否比排序更好(甚至不是二次的),这一点并不明显。
但在数学上,它的重现(也是最坏的情况)结果是
T(n) = T(n/5) + T(7n/10 + 6) + O(n)
可以用数学方法证明T(n) = O(n),因此它比排序要好。
也许是一种常见的看待它们的方式:
您可以将算法视为树,其中每个子问题都变成当前问题的子树,并且可以用完成的工作量标记节点,然后可以将每个节点的总工作量相加。
对于二分查找,工作量是O(1)(只是比较),其中一个子树,工作量是0,所以总工作量是O(log n)(本质上是一条路径,就像我们在二叉搜索树中所做的那样)。
对于合并排序,对于具有 k 个子节点的节点,工作量为 O(k)(合并步骤)。每个级别完成的工作是 O(n) (n, n/2 + n/2, n/4 + n/4 + n/4 + n/4 等),并且有 O(log n) 个级别,并且所以归并排序是 O(n log n)。
对于快速排序,在最坏的情况下二叉树实际上是一个链表,所以完成的工作是 n+n-1 + ... + 1 = Omega(n^2)。
对于选择排序,我不知道如何将其可视化,但我相信将其视为具有 3 个孩子(n/5、7n/10 和其余)的树可能仍然有帮助。