王道计算机408数据结构 笔记2

1.2.2 算法的时间复杂度

算法的效率应该怎么度量?

时间复杂度和空间复杂度

这一节主要讲解时间复杂度

怎么评估算法的时间开销?

传统思维:让算法先运行,事后统计运行时间

传统思维存在问题:

运行速度受机器性能影响,如超级计算机和单片机

和编程语言有关,越高级的语言效率越低,C就比Java快

和编译程序产生的机器指令质量有关(?)

有些算法不能事后统计,如导弹控制算法

(总体来说是有很多外部因素,我们需要排除外部因素;最后一条说明需要能事先估计)

算法时间复杂度:

事先估计算法时间开销T(n)与问题规模n的关系(T表示“time”)

 语句频度:

① 1次     ② 3001次    ③④ 3000次     ⑤ 1次

T(3000) = 1 + 3001 + 2*3000 + 1 (简化为每一个语句的耗时相同) 

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

问题1:当问题规模n足够大的时候可以忽略n的低阶部分,只保留最高阶部分,甚至可以忽略系数

如T(n)= 3n^3 + 3n^2 + 3 可以视为 T(n)= O(n^3)

 算法复杂度分析:

证明方法是高数的基本方法,这里不多展开 

结论1:顺序执行的代码只会影响常数项,可以忽略

结论2:只需挑选循环中一个基本操作他的执行次数与n的关系

当出现嵌套循环时:

 结论3:如果有多层嵌套循环时只需要关注最深层的循环次数与n的关系

 结论:很多算法的执行时间和输入时间有关

 一般只考虑最坏、平均时间复杂度

1.2.3 算法的空间复杂度

空间复杂度:

空间开销(内存开销)与问题n之间的关系

程序运行时的内存需求

例子:

 

 

函数递归调用带来的内存开销:

函数调用栈:

我们在编程中写的函数,会被编译器编译为机器指令,写入可执行文件,程序执行的时候,会把这个可执行文件加载到内存,在虚拟地址空间中的代码段存放。

如果在一个函数中调用另一个函数,编译器就会对应生成一条call指令,当程序执行到这条call指令时,就会跳到对应的函数入口处开始执行,而每一个函数的最后,都有一条ret指令,负责在函数结束后跳回到调用处继续执行。
(原文链接:https://blog.csdn.net/qq_29582443/article/details/123937089)

 2.1.0 线性表的定义和基本操作

定义就是逻辑结构,基本操作是运算,

后续会探讨不同的存储结构来实现线性表,相对性的运算也是不同的

线性表的定义(逻辑结构):

 (每一个数据元素的类型应当相同,各个数据元素所占的空间是一样大的,可帮助计算机快速找到某一数据元素;有限序列,首先要有限,整数列就不行,因为它无限,其实次要有序的数列)

线性表的基本操作

tips:

1、对数据的操作(记忆思路)——创销、增删改查

2、C语言函数的定义——<返回值类型>函数名(<参数1类型>参数1,<参数2类型>参数2,...)

3、在实际开发中,可以根据实际需求定义其他的基本操作

4、函数名和参数的形式和命名可以改变(我觉得最好统一)

5、当参数的修改结果需要带回来时,要引用“&”

 

 为什么要实现对数据结构的基本操作:

关于斐波那契数列用递归算法实现时的时间复杂度和空间复杂度:

 实际上需要统计运行次数的程序是:

if(N<3) return 1;

先码住,之后再写

递归求斐波那契数列的时间复杂度,不要被网上的答案误导了 - 知乎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值