学习素材:b站美女老师视频 https://www.bilibili.com/read/cv3285768
序
基本概念
- 程序=数据结构+算法
- 数据结构:操作对象以及操作对象间的关系。
存在关系的数据元素的集合。
数据元素间的关系称为结构。- 逻辑结构
- 物理结构(存储结构):数据及其关系在计算机内存中的表示。又称映像
- 运算和实现:对元素施加的操作,以及这些操作在存储结构中的实现。
- 数据:信息的集合
- 数据元素:数据的基本单位。简称:元素、记录、结点、顶点
- 数据项:构成数据元素的最小不可分割单位,记录中的一个字段
- 数据对象:性质相同的数据元素的集合,是数据的子集
- 逻辑结构分类:
- 线性结构:一对一。线性表、栈、队列、串
- 非线性结构
- 集合结构:结构中的数据元素除了同属一个集合外,没有其他关系
- 树:一对多
- 图(网):多对多
- 存储结构分类:
- 顺序存储结构:一组连续的存储单元来存储数据元素。数据元素之间的关系由由元素的存储位置来表示。例java中的数组
- 链式存储结构:一组任意的存储单元来存储数据元素。数据间的逻辑关系用指针表示。
- 索引存储结构:存储结点信息的时候,建个索引表。
- 散列存储结构:根据结点的关键字直接计算结点的存储地址。
- 数据类型:一组性质相同的值得集合,以及定义这个值集合上的一组操作的总称。
抽象数据类型(ADT):
三元组DSP:
* D:数据对象
* S:数据对象上的关系集
* P:数据对象的基本操作集
抽象数据类型的定义:
ADT 抽象数据类型名{
数据对象:<数据对象的定义>
数据关系:<数据关系的定义>
基本操作:<基本操作的定义>
}
//数据对象、数据关系的定义用伪代码描述
//基本操作的定义格式为:
// 基本操作名(参数表)
// 初始条件(初始条件描述)
// 操作结果(操作结果描述)
//参数表:包括赋值参数提供输入值,引用参数可以用来输入输出
例:
ADT Circle{
数据对象:D={r,x,y|r,x,t均为实数}
数据关系:S={<r,x,y>|r是半径,<x,y>是圆心坐标}
基本操作:
Circle(&C,r,x,y)
操作结果:构造一个圆
double Area(C)
初始条件:圆已存在
操作结果:计算面积
double Circumference(C)
初始条件:圆已存在
操作结果,计算周长
}ADT Circle
ADT Complex{
D={r1,r2|r1,r2都是实数}
S={<r1,r2>|r1是实部,r2是虚部}
assign(&C,v1,v2)
初始条件:空的负数C已存在
操作结果:构造负数C,r1,r2分别被赋以参数v1,v2的值
destroy(&C)
初始条件:复数C已存在
操作结果:复数C已被销毁
}ADT Complex
数据元素=数据的个体
数据对象=性质相同的数据元素构成的集合
数据结构=数据对象+数据元素之间的关系
存储结构=数据结构的映像到内存
存储结构包括:顺序、链式、索引、散列
逻辑结构=数据结构的逻辑模型
逻辑结构种类:集合、线性、树形、图状
算法:指令的有限序列
- 算法特性:
- 有穷性:步骤和时间都要有穷,不能无限。
- 确定性:每条指令必须有确切的含义,没有二义性。
- 可行性:可以通过已经实现的基本操作执行有限次来实现。
- 输入:有0个或多个输入
- 输出:有0个或多个输出
- 算法设计要求
- 正确性:算法满足问题要求,能正确解决问题,算法转化为程序后要注意
- 程序中不含语法错误
- 对于几组输入数据能够得出满足要求的结果
- 对于精心选择的、典型、苛刻且带有刁难性的几组输入数据能够得出满足要求的结果。
- 对于一切合法的输入数据都能得出满足要求的结果。
- 可读性:
- 算法主要是为了人的阅读和理解,应易于理解。
- 涩会难懂的算法容易隐藏错误。
- 健壮性
- 输入非法数据时,算法能恰当处理,而不是得到莫名其妙的结果。
- 处理出错时,不应该中断程序,而应该返回错误信息,以便在更高抽象层次上进行处理。
- 高效性:要求花费尽量少的时间和尽量低的存储需求
- 正确性:算法满足问题要求,能正确解决问题,算法转化为程序后要注意
算法的效率
- 度量
- 事后统计
- 事前分析:
- 算法运行时间=一个简单操作所需时间*简单操作次数
- 算法运行时间=sum(每条指令执行次数该语句执行一次所需时间)
算法运行时间=sum(每条语句频度该语句执行一次所需时间)
假设每条指令执行时间都为单位时间,那我们只需要考虑。指令执行次数和。
时间量度:时间复杂度
- 算法中每条语句的频度之和=算法所耗费的时间
- 为了便于比较不同算法的时间效率,我们仅比较它们的数量级。
- 若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n))为算法的渐进时间复杂度(O是数量级的符号),简称时间复杂度。
- 算法时间复杂度定义:
基本语句重复执行的次数=问题规模n的某个函数f(n),又称算法的时间量度,记作T(n)=O(f(n))
表示随着n增大,算法执行时间的增长率和函数f(n)的增长率相同,称渐进时间复杂度
数学符号[O]的定义:参考https://baike.baidu.com/item/%E5%A4%A7O%E7%AC%A6%E5%8F%B7/656100?fr=aladdin
若T(n)和f(n)是定义在正整数集合上的两个函数,则T(n)=O(f(n))表示存在正的常数C和n0,使得当n>=n0时满足0<=T(n)<=Cf(n)
???
-
算法中重复执行次数和算法的执行时间成正比的语句,对算法运行时间的贡献最大,执行次数最多。
-
n越大算法的执行时间越长,例:
排序:n为记录数
矩阵:n为矩阵的阶数
多项式:n为多项式的项数
集合:n为元素的个数
树:n为树的结点个数
图:n为图的定点数或边数 -
若f(n)是m次多项式,则T(n)=O(n^m)。忽略所有低次幂项和最高次幂系数,体现增长率的含义
-
分析算法时间复杂度的基本方法:
- 找出语句频度最大的语句作为基本语句
- 计算基本语句的频度得到问题规模n的某个函数f(n)
- 取其数量级,用符号O表示
-
基本操作的重复次数可能随输入集不同而不同
空间度量:空间复杂度
线性表
定义
- 线性表=具有相同特性的数据元素的有限序列
- 线性起点:起始结点,线性终点:终端结点