数据结构

数据结构 (Data Structure) 是带 结构 的数据元素的集合,“结构 指数据元素之间存在的关系

数据结构包括 逻辑结构 和 存储结构 两个层次,还有 数据运算 这个法则。

逻辑结构

逻辑结构脱离于计算机,是一种 从具体问题中抽象出来的 数学模型

该结构 需要两个构成因子:

  1. 数据

  2. 关系

常见类型

上面四种结构以 某班级学生作为数据对象 作为例子 来分别考察数据元素之间的关系

集合结构

数据元素之间除了 “ 属于同一集合 的关系外,别无其他关系。

例如,确定一名学生 是否为 班级成员,只需将班级看做一个集合结构。

线性结构

数据元素之间存在一对一的关系。

例如,将学生信息数据按照其入学报到的时间 先后顺序 进行排列,将组成一个线性结构。

树结构

数据元素之间存在一对多的关系。

例如,在班级的 管理体系 中,班长管理多个组长,每位组长管理多名组员,构成树形结构

图结构

数据元素之间存在多对多的关系。

例如,多位同学之间的朋友关系,任何两位同学都可以是朋友,从而构成图状结构

层次图

物理结构

数据对象在计算机中的存储表示 称为数据的 存储结构,也称为 物理结构

数据元素在计算机中有两种基本的存储结构,分别是 顺序存储结构链式存储结构

简单来讲就是 数组 和 链表

顺序存储结构

物理位置相邻 表示逻辑关系
• 占用一片连续的存储空间
• 支持随机存取(按下标 查找)

链式存储结构

借助指针/引用 表示逻辑关系
• 结点存储空间不一定连续(可连续可不连续)
• 支持顺序存取(必须从头节点开始找)

算法分析

算法的定义及特性

算法 (Algorithm) 是为解决某类问题而规定的 有限长操作序列

五个特性

特性说明
有穷性执行有穷步后结束,每步在有限时间内完成
确定性每步操作有确切规定,无二义性
可行性所有操作可通过已实现的基本操作有限次执行完成
输入零个或多个输入(通过形参传递)
输出一个或多个输出(通过返回值或引用形参返回)

评价标准

  • 正确性:合理输入下得到正确结果
  • 可读性:便于理解与交流(优先于机器可执行性)
  • 健壮性:非法输入能适当处理
  • 高效性:时间高效(时间复杂度)和空间高效(空间复杂度)

时间复杂度

定义:算法中基本语句重复执行的次数是问题规模 的某个函数 ,记作 ,表示算法执行时间的增长率和 的增长率相同。

符号 描述增长率的上限,即 (当 时)

一条语句的 重复执行次数 称作 语句频度(Frequency Count)

一个算法的执行时间大致上等于其 所有语句执行时间的总和,而语句的执行时间则为该条语句的 语句频度执行一次所需时间 的乘积。

注意

由于语句的执行要由源程序经编译程序翻译成目标代码,目标代码经装配再执行,因此 语句执行一次实际所需的具体时间 是与机器的软、硬件环境(如机器速度、编译程序质量等)密切相关的。

所以,所谓的算法分析 并非精确统计算法实际执行所需时间,而是针对算法中语句的执行次数做出估计,从中得到算法执行时间的信息。

分析方法

  1. 找出基本语句(频度最大的语句)
  2. 计算基本语句的频度
  3. 取数量级:忽略低次幂项和最高次幂系数, 为最高次幂)

常见复杂度

复杂度名称示例
常量阶单条语句、与 无关的循环
对数阶for(i=1; i<=n; i=i*2)
线性阶单层循环
线性对数阶快速排序等
平方阶双层循环
立方阶三层循环
指数阶效率极低, 稍大即不可用
阶乘效率最低

口诀 常对幂指阶

最好、最坏和平均时间复杂度

  • 最好:计算量可能达到的最小值
  • 最坏:计算量可能达到的最大值(最常用,作为执行时间的上界)
  • 平均:所有可能情况按等概率的加权平均值(通常难以确定)

空间复杂度

定义:算法所需存储空间的度量,记作

  • 只分析辅助空间:除输入数据外额外占用的存储空间
  • 原地工作:辅助空间为

示例

数组逆序,借助一个临时变量 ,借助大小为 的辅助数组为

时间复杂度和空间复杂度往往相互制约,但通常以时间复杂度为主要衡量指标。

Relax 1000 题

刷新对 逻辑结构存储结构 的认知

Caution

打个比方:

🏠 逻辑结构 = 房子的设计图
🧱 存储结构 = 房子的建造材料(砖头、木头、钢筋)

设计图 不依赖用什么材料建造,逻辑结构独立于存储结构
材料 是为了盖这栋楼而选的,存储结构不能脱离逻辑结构独立存在

具体例子,实现一个(逻辑结构:后进先出):

  • 存储结构 A:数组实现的栈
  • 存储结构 B:链表实现的栈

逻辑上都是”栈”,push/pop 行为一样;选哪种存储由需求决定,不是存储结构自己独立决定的。

反过来,不可能先有一块”链表内存布局”,再说它独立于任何逻辑结构——它一定是为表达某种逻辑关系才这样排列。

“独立”是逻辑对存储的单向独立,不是互相独立。