算法导论2-2

读书笔记

分析算法帮助我们选出某个问题的更优算法;

我们应该使用一个统一的标准去衡量算法的优劣,此处使用——RAM(random-access machine),一个通用的单处理器计算模型。

RAM模型对各种指令的执行时间定义为常量,注意,对于不同的指令该常量值不同;

对于插入排序,数据规模n和执行时间T,有着如下关系:

\[T(n) = c_1n + c_2(n-1) + c_4(n-1)+c_5\sum_{j=2}^nt_j+c_6\sum_{j=2}^n(t_j-1)\\+c_7\sum_{j=2}^n(t_j-1)+c_7(n-1) \]

如果数组已经是排好序的,那么这是该算法的最好情况;此时,数据规模n和执行时间T,关系如下:

\[T(n) =(c_1 + c_2+c_4+c_5+c_8)n - (c_2+c_4+c_5+c_8) \]

这是一个一元一次方程

如果数组完全是乱序的,那么这是该算法的最坏情况;此时,数据规模n和执行时间T,关系如下:

\[T(n) = \frac{c_5+c_6+c_7}{2}n^2+\frac{2c_1+2c_2+2c_4+c_5-c_6-c_7+2c_8}{2}n\\-(c_2+c_4+c_5+c_8) \]

这是一个一元二次方程;

一般来说,我们只考虑最坏的情况,为什么呢?

  1. 最坏情况让我们有个底
  2. 对于某些算法,最坏情况经常出现;
  3. 事实上,普通情况下的排序情况并没有比最坏情况好太多;

但是对我们来说,上述函数仍然有些复杂,对于较大的n,我们只需要关注增长级数高的一项,此处对应的是 \(\frac{c_5+c_5+c_7}{2}n^2\) ,然而面对大的输入,确定计算效率时,常量的影响不如\(n^2\),此时我们忽略这些常量;运行时间以\(\theta(n^2)\)记录;

课后习题

2.2-1

使用\(\theta\)记号表示函数\(\frac{n^3}{1000}-100n^2-100n+3\)

答案为:\(\theta(n^3)\)

2.2-2

考虑排序存储在数组A中的n个数:首先找出A中的最小元素并将其与A[1]中的元素进行交换。接着,找出A中的次最小元素将其与A[2]中的元素进行交换。对A中的前\(n-1\)个元素按该方式继续。该算法成为选择算法,写出其伪代码。该算法的循环不变式是什么?为什么它只需要对前\(n-1\)个元素进行操作,而不是对所有的n个元素操作?用\(\theta\)记号给出最好情况和最坏情况的运行时间。

for i = 1 to A.length -1{ 
    for j = A.length to A.length -i{
        if (A[j] > A[j-1]){
            result = j-1
        }
    }
    tmp = A[result]
    A[result] = A[i]
    A[i] = tmp
}

因为每次都从未排序的数组中选出最小的,当选了\(n-1\)个之后,就只剩下一个最大数;

\(\theta(n^2)\)

2.2-3

再次考虑线性查找问题,假定要查找的元素等可能的为数组中的任意元素,平均需要检查输入序列的多少元素?最坏的情况又如何?使用\(\theta\)记号给出线性查找的平均情况和最坏情况的运行时间?证明你的答案。

平均检查\(\frac{n+1}{2}\)个元素;

最坏检查\(n\)个元素;

时间复杂度为\(\theta(n)\)

2.2-4

对于任何一个算法,我们应该如何修改才能使之拥有最好的运行时间?

一种算法能够在一种情况下拥有最好的运行时间,并不意味着在其他更加普通的情况下拥有同样的表现。

posted @ 2021-01-14 17:53  ijkzen  阅读(176)  评论(0编辑  收藏  举报