[入门必看]数据结构1.2:算法和算法评价

Posted H3T

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[入门必看]数据结构1.2:算法和算法评价相关的知识,希望对你有一定的参考价值。

[入门必看]数据结构1.2:算法和算法评价


第一章 绪论

小题考频:8
大题考频:11


1.2 算法和算法评价

难度:☆☆☆

知识总览

数据结构

  • 基本概念
  • 什么是算法
  • 算法的五个特性
  • “好”算法的特质

1.2.1 算法的基本概念

  • 什么是算法?
    程序 = 数据结构 + 算法

数据结构:如何用数据正确地描述现实世界的问题,并存入计算机
算法:如何高效地处理这些数据,以解决实际问题

算法(Algorithm)是对特定问题求解步骤的一种描述,它是指令的有限序列,其中的每条指令表示一个或多个操作。

算法 - 求解问题的步骤

Eg. 要解决的问题:做番茄炒蛋

  1. 食材:鸡蛋、西红柿、料酒、糖、盐。 - 数据结构
  2. 处理食材的步骤:切西红柿、打鸡蛋、翻炒、调味、装盘。 - 算法

Eg.算法:将该线性表按照年龄递增排序
Step1:扫描5个元素,找到年龄最小的一个元素,插入到第1个位置Step 2:扫描剩下的4个元素,找到年龄最小的一个元素,插入到第2个位置
Step 3:扫描剩下的3个元素,找到年龄最小的一个元素,插入到第3个位置
Step 4:扫描剩下的2个元素,找到年龄最小的一个元素,插入到第4个位置

这是一个算法吗?


算法的特性

算法必须具备的特征:

  1. 有穷性。一个算法必须总在执行有穷步之后结束,且每一步都可在有穷时间内完成。

注:算法必须是有穷的,而程序可以是无穷
算法 - 用有限步骤解决某个特定的问题
程序 - 如:微信是程序,不是算法
 
死循环也不是算法

  1. 确定性。算法中每条指令必须有确切的含义,对于相同的输入只能得出相同的输出

Eg.
其中有两人的年龄相同,想要得到一个年龄递增的结果,上述两个排列结果都是正确的。
 
但是对于一个相同的输入,第一次处理后得到第一种结果,第二次处理后得到第二种结果,那么就不能称之为算法,其不具备确定性。
 
要求对于相同的输入,只能得出相同的输出,就是要求算法中的指令无歧义
 
加入一个无歧义的明确规则:对于岁数相同的元素,原本排在前的人,会被优先考虑,那么对于相同的输入就可以得到相同的输出。
 
所以对于刚才给出的算法描述中,是存在歧义的,其不具备确定性,不可以称为算法。

  1. 可行性。算法中描述的操作都可以通过已经实现的基本运算执行有限次来实现。

给出的实现方案必须能够用计算机代码来实现。

  1. 输入。一个算法有零个或多个输入,这些输入取自于某个特定的对象的集合。

给算法处理的数据
Eg. "Hello World! - 零个输入。
Eg. 上述排序案例,处理的数据来自个人财富数据对象 - 输入来自某个特定的数据对象

  1. 输出。一个算法有一个或多个输出,这些输出是与输入有着某种特定关系的量。

类似于函数:y=f(x)


“好”算法的特质

即设计算法时要尽量追求的目标

  1. 正确性。算法应能够正确地解决求解问题。

是算法 - 不是“好”算法

  1. 可读性。算法应具有良好的可读性,以帮助人们理解。

注:算法可以用代码、伪代码描述,甚至用文字描述,重要的是要“无歧义”地描述出解决问题的步骤
代码写//注释 - 提高可读性

  1. 健壮性。输入非法数据时,算法能适当地做出反应或进行处理,而不会产生莫名其妙的输出结果。


4. 高效率低存储量需求

高效率 - 花的时间少。时间复杂度
低存储量需求 - 不费内存。空间复杂度


1.2.2 算法效率的度量


算法效率的度量是通过时间复杂度空间复杂度来描述的。

时间复杂度

如何评估算法时间开销?
——让算法先运行,事后统计运行时间?

Q:存在什么问题?

  • 和机器性能有关,如:超级计算机v.s.单片机
  • 和编程语言有关,越高级的语言执行效率越低
  • 和编译程序产生的机器指令质量有关

能否排除与算法本身无关的外界因素

  • 有些算法是不能事后再统计的,如:导弹控制算法

能否事先估计?

算法时间复杂度:T = T(n)
事前预估算法时间开销T(n)问题规模n的关系
注:T表示“Time”

Eg.
用算法表白——“爱你n遍”

分析问题规模n与时间执行时间t之间的关系:
语句频度
①        ——1次
②        ——3001次
③④    ——3000次
⑤        ——1次

T(3000) = 1 + 3001 + 2*3000 + 1
时间开销与问题规模n的关系:
T ( n ) = 3 n + 3 T(n) = 3n + 3 T(n)=3n+3

问题1:是否可以忽略表达式某些部分?
问题2:如果有好几千行代码,按这种方法需要一行一行数?


简化时间复杂度

问题1:是否可以忽略表达式某些部分 - 能否简化时间复杂度
T 1 ( n ) = 3 n + 3 T_1(n) = 3n + 3 T1(n)=3n+3 - 3 n − n 3n - n 3nn
T 2 ( n ) = n 2 + 3 n + 1000 T_2(n) = n^2 + 3n + 1000 T2(n)=n2+3n+1000 - n 2 n^2 n2
T 3 ( n ) = n 3 + n 2 + 9999999 T_3(n) = n^3 + n^2 + 9999999 T3(n)=n3+n2+9999999 - n 3 n^3 n3
当问题规模n足够大时,可以忽略掉低阶的项。

若n=3000,则
3 n = 9000 3n = 9000 3n=9000                        V.S.         T 1 ( n ) = 9003 T_1(n)=9003 T1(n)=9003
n 2 = 9 , 000 , 000 n^2=9,000,000 n2=9,000,000              V.S.         T 2 ( n ) = 9 , 010 , 000 T_2(n)=9,010,000 T2(n)=9,010,000
n 3 = 27 , 000 , 000 , 000 n^3=27,000,000,000 n3=27,000,000,000   V.S.         T 3 ( n ) = 27 , 018 , 999 , 999 T_3(n)=27,018,999,999 T3(n)=27,018,999,999

  • 结论1:可以只考虑阶数高的部分


T ( n ) = O ( f ( n ) ) ⇔ lim ⁡ n → ∞ T ( n ) f ( n ) = k T\\left( n \\right) =O\\left( f\\left( n \\right) \\right) \\Leftrightarrow \\undersetn\\rightarrow \\infty\\lim\\fracT\\left( n \\right)f\\left( n \\right)=k T(n)=O(f(n))nlimf(n)T(n)=k

当n=3000时,
9999 n = 29 , 997 , 000 9999n = 29,997,000 9999n=29,997,000          远小于      n 3 = 27 , 018 , 999 , 999 n^3=27,018,999,999 n3=27,018,999,999
当n=1000000时
9999 n = 9 , 999 , 000 , 000 9999n=9,999,000,000 9999n=9,999,000,000    远小于      n 2 = 1 , 000 , 000 , 000 , 000 n^2=1,000,000,000,000 n2=1,000,000,000,000

  • 结论2:问题规模足够大时,常数项系数也可以忽略

在分析一个程序的时间复杂性时,有以下两条规则:

  1. 加法规则
    T ( n ) = T 1 ( n ) + T 2 ( n ) = O ( f ( n ) ) + O ( g ( n ) ) = O ( max ⁡ ( f ( n ) , g ( n ) ) ) T\\left( n \\right) =T_1\\left( n \\right) +T_2\\left( n \\right) =O\\left( f\\left( n \\right) \\right) +O\\left( g\\left( n \\right) \\right) =O\\left( \\max \\left( f\\left( n \\right) ,g\\left( n \\right) \\right) \\right) T(n)=T1(n)+T2(n)=O(f(n))+O(g(n))=O(max(f(n),g(n)))
    多项相加,只保留最高阶的项,且系数变为1

  2. 乘法规则
    T ( n ) = T 1 ( n ) × T 2 ( n ) = O ( f ( n ) ) × O ( g ( n ) ) = O ( f ( n ) × g ( n ) ) T\\left( n \\right) =T_1\\left( n \\right) \\times T_2\\left( n \\right) =O\\left( f\\left( n \\right) \\right) \\times O\\left( g\\left( n \\right) \\right) =O\\left( f\\left( n \\right) \\times g\\left( n \\right) \\right) T(n)=T1(n)×T2(n)=O(f(n))×O(g(n))=O(f(n)×g(n))
    多项相乘,都保留

Eg.
T 3 ( n ) = n 3 + n 2 l o g 2 n T_3(n)=n^3+n^2log_2n T3(n)=n3+n2log2n
             = O ( n 3 ) + O ( n 2 l o g 2 n ) =O(n^3)+O(n^2log_2n) =O(n3)+O(n以上是关于[入门必看]数据结构1.2:算法和算法评价的主要内容,如果未能解决你的问题,请参考以下文章

机器学习机器学习入门02 - 数据拆分与测试&算法评价与调整

入门必看-算法基础知识讲解小白都也能看得懂

数据结构-1.2什么是算法

数据结构-1.2什么是算法

清风:数学建模算法编程和写作培训

这8种常见的Java排序算法,学算法必看!