数据结构与算法
什么是算法
有具体的问题
有设计解决这个问题的具体流程
有评价处理流程的可量化指标
评估算法优劣的核心指标
时间复杂度(流程决定)
额外空间复杂度(流程决定)
常数项时间(实现细节决定)
常数项时间
如果一个操作的执行时间不以具体样本量为转移,每次执行时间都是固定时间。称这样的为常数时间操作。比如:数组的索引,无论下标为多少,始终都是计算偏移量 -> 索引
这两个步骤。常见的常数时间操作有:
常见的算数运算:+、-、*、/、%等
常见的位运算:<<、>>、>>>、|、&、^等
赋值、比较、自增、自减操作等
数组的寻址操作
执行时间固定的操作都是常数时间操作,自行时间不固定的都不是常数时间操作。常数时间操作的时间复杂度都为
O(1)
时间复杂度
如何确定算法流程的总操作数量与样本数量之间的表达式?
按照算法的最差情况计算
将流程彻底拆分一个个基本动作,保证每个动作都是常数时间的动作
假设数量为N,看基本动作与N之间的关系
如何确定时间复杂度?
当完成了表达式的建立,只要将高阶项留下即可。低阶项、高阶项系数全部去除,记为: O(高阶项)
。
为什么可以忽略低阶项、高阶项系数?
当数据量足够大的时候,低阶项、高阶项对于算法效率的影响很小,算法的时间复杂度基本就由高阶项决定。
时间复杂度的意义?
衡量算法流程复杂度的指标,该指标只与数据量有关,与过程之外的优化无关。
额外空间复杂度
在实现算法流程的过程中,需要开辟一些空间来支持你的算法流程,另外:
作为输入参数的空间,不算做额外空间
作为输出结果的空间,也不算额外空间
除此之外的这部分空间就是额外空间。如果你的算法只需要开辟有限的几个变量,即与输入数据量无关,那么额外空间复杂度为O(1)
。
算法问题最优解
一般情况下,认为解决一个问题的算法流程,在时间复杂度指标上,一定要尽可能的低,先满足了时间复杂度最低的指标后,使用最少的额外空间复杂度的算法流程,叫做这个算法问题的最优解。
一般说起算法最优解都是忽略常数项这个因素,因为这个因素只决定了实现层次的优化和考虑,而和怎么解决整个问题的思想无关。
常见的时间复杂度
O(1)
O(logN)
O(N)
O(N*logN)
O(N^2)
,O(N^3)
...O(N^K)
O(2^N)
,O(3^N)
...O(K^N)
O(N!)
对数器
通常我们在笔试的时候或者参加编程大赛的时候,自己实现了一个算法,但是不能够判断该算法是否完全没问题,如果在比赛平台上验证,通常只会告诉你有没有错误,出了错不会告诉你哪里有问题,对于排错来说是非常坑爹的,所以对数器就横空出世了,对数器就是用一个绝对OK的方法和随机器生成的样本数据进行合体,如果你的算法是没问题的,那么和对数器的这个百分之百正确的方法一个元素一个元素的比较,也一定是equals的。如果返回false,说明你的算法有问题。
什么是对数器?
有一个你想要测的方法a;
实现一个绝对正确但是复杂度不好的方法b;
实现一个随机样本产生器;
实现对比算法a和b的方法;
把方法a和方法b比对多次来验证方法a是否正确;
如果有一个样本使得比对出错,打印样本分析是哪个方法出错;
当样本数量很多时比对测试依然正确,可以确定方法a已经正确。
针对插入排序的样例:
什么是数据结构
数据结构的分类可以从两个角度分类:
物理结构
逻辑结构
其中物理结构可以分为:
连续结构,比如数组
连续结构在内存中是一块连续的内存;查找元素时,直接计算偏移量,速度较快;但是元素发生修改时,会重新移动内存,比较慢。
跳转结构,比如单链表
跳转结构中的每个元素中包含下上或者下个元素的内存地址;查找元素时,需要依次遍历寻找每个元素匹配,速度较慢;元素发生修改比较快,不用重新移动内存,直接更改指针即可。
如果按照逻辑结构划分,可以划分为如下结构:
最后更新于
这有帮助吗?