数据结构mooc学习

来源:互联网 发布:淘宝联盟旧版本5.2 编辑:程序博客网 时间:2024/05/17 04:02

数据结构mooc学习

清华大学学堂在线 邓俊辉老师 deng@tsinghua.edu.cn


第1章 绪论

(a)计算

计算=信息处理

对象:规律,技巧 目标:高效,低耗

何为计算:借助某种工具,遵照一定规则,以明确而机械的形式进行。

计算模型=计算机=信息处理工具

算法:

输入:待处理的信息(问题)

输出:经处理的信息(答案)

正确性:的确可以解决指定的问题

确定性:任一算法都可以描述为一个有基本操作组成的序列

可行性:每一基本操作都可实现,且在常数时间内完成

有穷性:对于任何输入,经有穷次基本操作都可以得到输出

例子:Hailstone问题

例子:Hailstone问题

什么是个好算法:正确,健壮,可读,效率

Data Structure + Algorithms = Programs


(b)计算模型

成本:运行时间+存储空间

特定算法+不同实例, 以及,不同算法+特定实例

图灵机 Turing Machine

包括:纸带,读写头,Transition Function

(q,c,d,L/R,p) 表示若当前状态为q且当前字符为c,则将当前字符改写为d,转向左侧/右侧的邻格,转入p状态,一旦转入特定的终止状态 ‘h’ ,则停机。

例子:图灵机实例

例子:图灵机实例

RAM模型概念

RAM模型概念

在这些算法中,算法的运行时间成正比于算法需要执行的基本操作次数。

RAM模型的实例

RAM模型的实例

执行过程可以记录为一张表,表的行数即是所执行的基本指令的总条数,能够客观度量算法的执行时间。

图灵机(TM),RAM等模型为度量算法性能提供了准确的尺度。


(c)大O记号(Big O Notation)

Paul Bachmann 1894 同阶无穷小

Mathematics is more in need of good notations than of new theorems. —-Alan Turing

长远,主流

渐进分析 Asymptotic analysis:

当n>>2后,对于规模为n输入,

算法需执行的基本操作次数:T(n)=?? 需占用的存储单元数:S(n)=??

T(n) = O(f(n)) iff c>0,当 n>>2 后,有 T(n) < c*f(n) 。

O(1):常数复杂度,2=2017=…=2011111111=O(1)

O((logn)c):对数多项式的复杂度 (poly log function)

对数:O(logn) lnn, lgn, … , 与对数的底数无关

常底数无所谓: ablogan=logablogbn=O(logbn)

常数次幂无所谓: c>0,lognc=clogn=O(logn)

对于对数多项式而言,取对数多项式里面次数最高的项即可

此类算法非常有效,因为复杂度无限接近于常数。

c>0, n充分大时,O(logn) 小于 nc

O(nc),多项式复杂度,polynomial function

O(2n),指数(exponential function) 指数爆炸

这类算法的计算成本增长极快,通常被认为是不可忍受的,从O(nc)O(2n)

是从有效算法到无效算法的分水岭,很多问题的O(2n)算法显而易见,

然而,设计出O(nc)算法却极为不易,甚至,有时注定地只能是徒劳无功。

2-Subset 问题,美国大选实例

2-Subset 问题,美国大选实例

对于2-Subset 问题,

直觉算法:逐一枚举S集中的每一个子集,并统计其中元素的总和,须2n轮。

亦即:在最坏的情况下,必须花费2n的时间,不甚理想!

直觉提出的问题:是否有更好的算法?

定理:2-Subset is NP-complete

not Polynomial, 非多项式时间内完成

即:就目前的计算模型而言,不存在可以在多项式时间内回答此问题的算法,就此意义而言

上述的直觉算法已经属于最优。

O(2n)>O(n3)>O(n2)>O(nlogn)>O(n)>O(n)>O(logn)>O(1)


(d)算法分析

去粗存精

He(Euler) calculated just as men breathe, as eagles sustain themselves in the air. — —Francois Arago

两个主要任务:正确性(不变性*单调性)+复杂度

复杂度分析的三个主要方法:

迭代:级数求和

递归:递归跟踪+递推方程

猜测+验证

级数的知识:

算术级数:与末项平方同阶

T(n)=1+2+...+n=n(n+1)2=O(n2)

幂方级数:比幂次高出一阶

T2(n)=12+22+...+n2=n(n+1)(2n+1)6=O(n3)

T3(n)=13+23+...+n3=n2(n+1)24=O(n4)

T4(n)=14+24+...+n4=n(n+1)(2n+1)(3n2+3n1)30=O(n5)

nk=0kdn0xd+1dx=1d+1xd+1|n0=1d+1nd+1=O(nd+1)

几何级数(a>1):与末项同阶

Ta(n)=a0+a1+...+an=(an+11)a1=O(an)

20+21+...+2n=2n+11=O(2n+1)=O(2n)

收敛级数:常数复杂度

12+123+134+...+1n1n=11n=O(1)

1+122+132+...+1n2<1+122+132+...=π26=O(1)

有必要讨论这类级数吗?难道基本操作次数,存储单元数可能是分数?

例子:几何分布(击中目标的命中率为p,击不中的概率为q,p+q=1)

首次击中所用次数的期望:

p(1+2q+3q2+...)=pk=1kqk1=1p=O(1)

可能未必收敛,然而长度有限的级数:

1+12+13+...+1n=O(logn)

log1+log2+log3+...+logn=logn!=O(nlogn)

循环&&级数

for(int i=0;i<n;i++)    for(int j=0;j<n;j++)

算法复杂度: n2=O(n2)

for(int i=0;i<n;i++)    for(int j=0;j<i;j++)

算法复杂度: n(n1)2=O(n2)

算法复杂度的一个实例

算法复杂度的一个实例

实例:取非极端元素
实例:取非极端元素

起泡排序算法
起泡排序算法

不变性:经k轮扫描交换后,最大的k个元素必然就位;
单调性:经k轮扫描交换后,问题的规模缩减至n-k;
正确性:经之多n趟扫描后,算法必可终止,得出正确解答。

封底计算(可在信封背面估算出答案) Back of the envelope calculation


(e)迭代与递归

To iterate is human, to recurse, divine.
迭代乃人工,递归显神通。

数组求和:迭代

问题:计算任意n个整数之和

实现:逐一取出每个元素,累加之。

int SumI(int A[],int n){   int sum=0;    for(int i=0;i<n;i++)        sum+=A[i];    return sum;}

无论A[ ]的内容如何,都有T(n)=O(n);

空间:(不算开始时的存储输入,而算另外开辟的存储空间)2个,sum和 i

减而治之:(Decrease and Conquer)

原始的大问题,分解为两个子问题,其一为平凡的,另一为规模缩减的。

数组求和:线性递归
数组求和:线性递归

递归跟踪:直观形象,仅适用于简明的递归模式;

递推方程:简洁抽象,更适用于复杂的递归模式。

上述的递推方程

上述的递推方程

数组倒置

数组倒置

分而治之:(Divide and Conquer)

将原问题划分为两个规模相当的子问题。

数组求和:二分递归

数组求和:二分递归

二分递归的递推关系式

二分递归的递推关系式

0 0
原创粉丝点击