翻陈年老底翻到了之前的数据结构笔记,由于当时刚开始使用电脑记笔记,markdown语法用的还是不是很熟,以及技术上比较欠缺,望多多海涵。
来都来了,点个赞呗~
数据结构大体框架
早期>>数值计算>>计算机元素间关系简单,计算复杂
如今>>非数值计算>>计算机元素间关系复杂,计算简单
非数值计算呈现形式:表、树、图······
基础概念介绍
1、**数据:**能输入计算机且能被计算机处理的各种符号的集合
**包括:**数值型数据:整数、实数等
非数值型数据:文字、图像、图形、声音
2、**数据元素:**是数据的基本单位,在计算机中通常作为一个整体进行考虑和 处理,也简称为元素 、结点
3、数据项:构成数据元素的不可分割的最小单位
数据>数据元素>数据项
例如:学生信息表>学生>学号、姓名
4、**数据对象:**是性质相同的数据元素的集合,是数据的一个子集
对比:
数据元素是数据的个体
数据对象是数据的子集
数据结构概念
① 定义:
数据元素之间的相互关系成为结构;数据结构是带结构的数据元素的集合
② 内涵:
逻辑结构——数据元素间的逻辑关系
存储结构——数据元素以及关系在计算机内存中的表示
运算和实现——对数据元素可以施加的操作以及这些操作在相应的存储结构与上的实现
关系:逻辑结构是数据结构的抽象,存储结构式数据结构的实现
③ 逻辑结构的种类:
划分方式一:
线性结构
特点有且仅有一个开始和一个终端结点,并且所有节点都最多只有一个直接前驱和一个直接后驱**(就是一条路走到黑,一对一)**
例如:线性表、栈、队列、串
非线性结构
一个结点可能有多个直接前驱和直接后继**(一对多、多对多)**
例如:树、图
划分方式二:
**集合结构:**无关系
**线性结构:**一对一
**树形结构:**一对多
**图状结构:**多对多
④ 存储结构的种类
- 顺序存储结构:
用一组连续的存储单元依次存储数据元素,C语言中使用数组来实现顺序存储结构
- 链式存储结构:
用一组任意的存储单元存储数据元素,C语言中使用指针来实现链式存储结构
- 索引存储结构:
在存储结点信息的同时,还建立附加的索引表
- 散列存储结构:
根据结点的关键字直接计算出该结点的存储地址
数据类型和抽象数据类型:
数据类型(DT)定义:
是一组性质相同的值的集合以及定义于这个值集合上一组操作的总称
抽象数据类型(ADT)定义:
是一个数学模型以及定义再次数学模型上的一组操作
从问题抽象出数据模型并定义抽象运算
C语言数据类型:
基本数据类型:int,char,float,double等
构造数据类型:数组、结构、共用体、枚举等
其他数据类型:指针、空(void)
typedef自己定义数据类型
抽象数据类型的形式定义:
抽象数据类型可以用(D,S,P)三元组表示
D是数据对象;
S是D上的关系集;
P是对D的基本操作集
一个抽象数据类型的定义格式如下:
ADT 抽象数据类型名{
数据对象:<数据对象的定义>
数据关系:<数据关系的定义>
基本操作:<基本操作的定义>
}ADT 抽象数据类型名
数据对象、数据关系的定义用伪代码描述
基本操作的定义格式为:
下面的这部分可能会比较抽象,可以先从概念上理解每部分的作用即可,不必硬记格式
· 基本操作名(参数表)
赋值参数 为操作提供输入值
引用参数 用&开头,提供输入值+返回操作结果
· 初始条件:<初始条件描述>
描述操作执行之前数据结构和参数应该满足的条件;若操作失败,返回相应出错信息;若初始条件为空,则省略
· 操作结果:<操作结果描述>
说明操作正常完成之后,数据结构的变化状况和应返回的结果
例子:Circle定义
算法概念
1、定义:
对特定解决问题方法和步骤的一种描述
程序=数据结构+算法
**关系: **数据结构通过算法实现操作;算法根据数据结构设计程序
2、特性:
① 有穷性 执行有穷步,有穷时间内完成
② 确定性 指令有确切含义,无二义性,否则容易引起误解
③ 可行性 可以执行,即点“运行”的时候不会发生异常而导致程序无法进行
④ 输入 可以是0个
⑤ 输出 必须要有输出
3、设计要求
· 正确性 尤其要关注边缘值、特殊值的输入数据能否满足
· 可读性 注意人能不能看懂
· 健壮性 输入非法数据时,算法要有恰当反应
· 高效性 花费尽量少的时间和尽量低的存储需求
4、评价
时间效率+空间效率
算法的时间效率和空间效率有时候是矛盾的
① 时间效率
1)衡量:消耗时间=执行一次简单操作时间×简单操作次数(语句频数)
简单操作时间主要由机器本身软硬件环境决定的,所以设计算法的过程中考虑语句频度即可
我们把算法所耗费的时间定义为该算法中每条语句的频度之和T(n)函数
2)渐进时间复杂度:
T
(
n
)
=
O
(
f
(
n
)
)
T(n)=O(f(n))
T(n)=O(f(n))
利用时间复杂度可以具体算出频度之和,但是,对于大程序而言往往这样做起来比较复杂,而且有些操作对复杂度贡献较小,于是我们可以利用等价无穷大的思想,计算渐进时间复杂度。不必考虑计算所有操作的执行次数,只考虑算法中基本操作的执行次数。并取最高次幂。
例题:分析以下程序段的时间复杂度:
尝试列举分析:
3)时间复杂度分类:
(1)最坏时间复杂度:最坏情况下,算法的时间复杂度
(2)平均时间复杂度:在所有可能输入示例在等概率出现的情况下,算法的期望运行时间
(3)最好时间复杂度:最好情况下,算法的时间复杂度
一般总考虑最坏情况下的时间复杂度,以保证算法运行的时间不会比它更长
对于复杂的算法,可以将其分为几个不同的部分,然后利用加法法则和乘法法则计算算法的时间复杂度
a) 加法法则:
T
(
n
)
=
T
1
(
n
)
+
T
2
(
n
)
=
O
(
f
(
n
)
)
+
O
(
g
(
n
)
)
=
O
(
m
a
x
(
f
(
n
)
,
g
(
n
)
)
)
T(n)=T1(n)+T2(n)=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(max(f(n),g(n)))
b) 乘法法则:
T
(
n
)
=
T
1
(
n
)
∗
T
2
(
n
)
=
O
(
f
(
n
)
)
∗
O
(
g
(
n
)
)
=
O
(
f
(
n
)
∗
g
(
n
)
)
T(n)=T1(n)*T2(n)=O(f(n))*O(g(n))=O(f(n)*g(n))
T(n)=T1(n)∗T2(n)=O(f(n))∗O(g(n))=O(f(n)∗g(n))
4)几种常见时间复杂度比较
常数阶<对数阶<线性阶<线性对数阶<平方阶<立方阶<······<k次方阶<指数阶
② 空间效率
渐进空间复杂度:
S
(
n
)
=
O
(
f
(
n
)
)
S(n)=O(f(n))
S(n)=O(f(n))