some small modifications

This commit is contained in:
Shine wOng
2019-05-16 18:31:13 +08:00
parent 3dd8cd9221
commit ba403fcde0

View File

@@ -90,7 +90,7 @@ T(n) = O(n^2)
$$
分摊到每次操作的时间成本为$O(n)$
同样接下来再考虑加倍策略。同样是最坏情况下连续进行了n次插入操作。假定初始的容量为每次扩容所需要的时间成本为
同样接下来再考虑加倍策略。同样是最坏情况下连续进行了n次插入操作。假定初始的容量为1,每次扩容所需要的时间成本为:
$$
1, 2, 4, 8, ..., n
$$
@@ -197,7 +197,7 @@ int Vector<T>::search(T e, int lo, int hi){
但是邓公说,对于这种经常要用到的算法,还需要考察它复杂度的系数。所以实际上它的时间复杂度是$O(1.50logn)$,这个证明暂时还不会。我们对这个算法进行一个细致的分析:
可以看到,这个算法虽然是_二分_查找,可是实际上左右两边的操作时间并不是平衡的,进入边需要更高的时间代价。这是因为进入边只需要一次比较,而进入边需要两次比较,所以边的时间代价更高。左右两边不平衡会导致这个算法的运行速度变慢,也意味着还有可以优化的办法。
可以看到,这个算法虽然是<em>二分</em>查找,可是实际上左右两边的操作时间并不是平衡的,进入边需要更高的时间代价。这是因为进入边只需要一次比较,而进入边需要两次比较,所以边的时间代价更高。左右两边不平衡会导致这个算法的运行速度变慢,也意味着还有可以优化的办法。
> 斐波拉契查找
@@ -287,7 +287,7 @@ int Vector<T>::interpolation_search(T const &elem, int lo, int hi){
}
```
插值查找在平均情况下,每经过一次比较,规模从$n$缩减到$\sqrt(n)$,其平均时间复杂度为$O(loglog n)$(需要证明,但是目前不会)。这个结果虽然看起来很理想,但是在目前人类的数据量看来,和$O(logn)$相比并不占多大优势(考虑$2^64$的数据量)。
插值查找在平均情况下,每经过一次比较,规模从$n$缩减到$\sqrt{n}$,其平均时间复杂度为$O(loglog n)$(需要证明,但是目前不会)。这个结果虽然看起来很理想,但是在目前人类的数据量看来,和$O(logn)$相比并不占多大优势(考虑$2^{64}$的数据量)。
此外,插值查找在大数据量的输入下,表现会比较好。但是,一旦数据量缩小到一定范围,就容易受到局部扰动的影响,从而耽误大量的时间,例如整体的数据分布是线性分布,却又一个小局部不满足线性分布,是二次分布的。所以,理想的查找方法是
@@ -323,7 +323,7 @@ bool Vector<T>::bubble(int lo, int hi){
> 对上面版本的冒泡排序进行优化
考虑一种情况即一个规模为n的Vector中已经是局部有序了只有前面k个元素是无序的。使用上面的算法的话在最坏情况下时间复杂度为$O(n * k)$。假定$ k = \sqrt(n)$,则时间复杂度为$O(n^{3/2})$。
考虑一种情况即一个规模为n的Vector中已经是局部有序了只有前面k个元素是无序的。使用上面的算法的话在最坏情况下时间复杂度为$O(n * k)$。假定$ k = \sqrt{n}$,则时间复杂度为$O(n^{3/2})$。
但是实际上它根本不需要这么高的时间复杂度。因为要是可以检测到该序列的局部有序性只给前面的k个元素排序的话就只需要$O(k^2) = O(n)$的时间代价就可以完成。