算法与数据结构【算法】——一、基本概念与复杂度分析
一、基本概念
(1)程序 = 算法+数据结构
- 程序设计:为计算机处理问题编制的一组指令集
- 算 法:处理问题的策略
- 数据结构:问题的数学模型
(2)数据与数据结构
- 数据(计算机处理/操作的对象)
- 数据元素(数据结构的基本单位)
- 数据项(数据结构的最小单位)
- 数据结构(带结构的数据元素的集合)—— 结构:次序关系、逻辑结构
- 逻辑结构:线性、树状、图状、集合
- 存储结构:逻辑结构在存储器中的映象
- 原理: 数据结构 = 数据元素集 + 数据关系集
- 数据元素的映象:用二进制位(bit)的位串表示数据元素
- 关系的映象:顺序映象(相对位置存储后继)、链式映象(附加信息存储后继,如指针)
(3)数据类型
值的集合 + 定义集合上的一组操作
(4)抽象数据类型 Abstract Data Type | ADT
定义:一个数学模型(数据对象D、数据关系S) 以及 定义在此数学模型上的一组操作P。
描述方法:(D,S,P)
-
基本操作:
- 基本操作名:参数表;
- 初始条件:操作执行前的数据结构和参数条件,不满足则操作失败返回出错信息;
- 操作结果:操作正常完成后,数据结构的变化状况和返回结果;
- 赋值参数:操作的输入值;
- 引用参数:以&打头的输入值,并返回操作结果;
-
特征
- 数据抽象:强调其本质特征,其完成的功能以及它和外部用户的接口
- 数据封装:将实体的 外部特性 和 内部实现 细节分离,并对外部用户隐藏内部实现细节。
-
C语言描述
- 存储结构定义:
- typedef struct { float realpart; float imagpart; }complex;
- 基本操作的函数原型说明
- void Assign( complex &Z, float realval, float imagval );
- 存储结构定义:
(5)算法
- 定义:为了解决某类问题而规定的一个有限长的操作序列。
- 五个重要特性:
- 有穷性(有限时间、又穷步骤)
- 确定性(算法执行路径确定)
- 可行性(操作基本)
- 有输入
- 有输出
- 算法设计的原则:
- 正确性:满足需求(无语法错误 -> 对于输入有正确结果 -> 刁钻数据可【衡量算法合格的原则】 -> 一切数据可)
- 可读性:易于理解
- 健壮性:以返回错误的输出值,处理出错现象
- 高效率与低存储量需求:效率 为 算法执行时间,存储量 为 算法所需的最大存储空间。两者相关问题规模。
- 算法效率的衡量方法
- 事后统计法
缺陷:1) 必须执行程序;2) 其它因素(测试环境、数据规模)掩盖; - 事前分析估算法
- 事后统计法
二、时间复杂度
(1)基本原理
- 时间相关因素:
- 算法选用的策略;
- 问题的规模;
- 编写程序的语言;
- 编译程序产生的机器代码的质量;
- 计算机执行指令的速度
- 时间复杂度:
- 依赖问题规模:算法的“运行工作量”大小,只依赖于问题的规模
- 大 O 复杂度表示法:
- 估计方法
- 原理:因为 [算法 = 控制结构 + 原操作],而 [算法的执行时间 = Σ 原操作(i)的执行次数×原操作(i)的执行时间],假定原操作执行时间相同,则只与 [原操作执行次数之和成正比]
- 结论:以 该基本操作在算法中重复执行的次数 作为算法运行时间的衡量准则。
- 做法:只关注基本操作
- 算法的(渐近)时间复杂度: T (n) = O(f(n))
- T(n) :表示代码执行的时间;
- n:表示数据规模的大小;
- f(n):表示每行代码执行的次数总和。
- O:表示代码的执行时间 T(n) 与 f(n) 表达式成正比。
- 总结 —— 只考虑 f(n) 的数量级
- 估计方法
- 实用技巧
- 只关注循环执行次数最多的一段代码
- 加法法则:总复杂度等于量级最大的那段代码的复杂度
- T(n)=T1(n)+T2(n)=max(O(f(n)), O(g(n))) =O(max(f(n), g(n)))
- 乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积
- T(n)=T1(n)*T2(n)=O(f(n))*O(g(n))=O(f(n)*g(n))
(2)分类
多项式量级
- 常量级:O(1) —— 只要算法中不存在循环语句、递归语句,其时间复杂度均为 Ο(1)。
- 对数阶:O(logn)、O(nlogn) —— 对数阶的时间复杂度不管底数 —— 在采用大 O 标记复杂度的时候,可以忽略系数,即 O(Cf(n)) = O(f(n))
- 复合型:O(m+n)、O(m*n) —— 涉及 m,n 两个规模
- 线性阶 与 K次方阶:O(n)、O(n2)、…、O(nk)
非多项式量级
包含:O(2n) 和 O(n!)
时间复杂度为非多项式量级的算法问题叫作 NP(Non-Deterministic Polynomial,非确定多项式)问题。
低效性:当数据规模 n 越来越大时,非多项式量级算法的执行时间会急剧增加,求解问题的执行时间会无限增长。
(3)时间复杂度具体分析
最好情况时间复杂度(best case time complexity)
在最理想的情况下,执行这段代码的时间复杂度。
最坏情况时间复杂度(worst case time complexity)
在最糟糕的情况下,执行这段代码的时间复杂度
平均情况时间复杂度(average case time complexity)
平均时间复杂度的全称为加权平均时间复杂度或者期望时间复杂度,需要考虑所有情况发生的概率与其对应时间复杂度。
均摊时间复杂度(amortized time complexity)
特殊场景:(1)大部分情况为普通时间复杂度,少部分情况下时间复杂度偏高;(2)两种时间复杂度,出现的频率是有规律的,有一定的前后时序关系,即周期性
应用:将高复杂度 按照周期性均摊给 若干个低复杂度。
在能够应用均摊时间复杂度分析的场合,一般均摊时间复杂度就等于最好情况时间复杂度。
三、空间复杂度
- 算法的空间复杂度:表示算法的存储空间与数据规模之间的增长关系。S(n) = O(g(n))
- 算法的存储量包括:
- 输入数据所占空间;
- 程序本身所占空间;
- 辅助变量所占空间 。
- 关于辅助变量
- 若输入数据所占空间只取决于问题本身,和算法无关,则只需要分析除输入和程序之外的辅助变量所占额外空间。
- 若所需额外空间相对于输入数据量来说是常数,则称此算法为原地工作。
- 若所需存储量依赖于特定的输入,则通常按最坏情况考虑。