没错又是我,持续更新我的笔记,这门笔记是数据结构与算法
文章目录
绪论
1.1基本概念和术语
1.1.1 数据 数据元素 数据项和数据对象
数据
是能输入计算机且能被计算机处理的各种符号的集合
- 信息的载体
- 是对客观事物符号化的表示
- 能够被计算机识别、存储和加工
包括了:
- 数值型的数据: 整数、实数等
- 非数值型数据: 文字、图像、图形、声音等
数据元素
- 是数据的基本单位,在计算机中通常作为一个整体进行
- 也简称为元素,或成为记录、结点或顶点
数据项
- 构成数据元素的不可分割的最小单位
三者的关系: 数据 > 数据元素 > 数据项
例如: 学生表 > 个人纪录 > 学号(姓名)
数据对象
-
是性质相同的数据元素的集合,是数据的一个子集
例如: 整数数据对象是集合N = {0, ±1,±2…}
1.1.2 数据结构
- 数据元素不是孤立存在的,他们之间存在着某种关系,数据元素相互之间的关系成为结构
- 是指相互之间存在一种或多种特定关系的数据元素集合
- 或者说,数据结构是带结构的数据元素的集合
数据结构包括以下三方面的内容:
- 数据元素之间的逻辑关系,也成为逻辑结构
- 数据元素及其关系在计算机内存中的表示(又称为映像),成为数据的物理结构或数据的储存结构
- 数据的**运算和实现,**即对数据元素可以世家的操作以及这些操作在相应的存储结构上的实现.
逻辑结构:
- 描述数据元素之间的逻辑关系
- 与数据的存储无关,独立于计算机
- 是从具体问题抽象出来的数学模型
物理结构:
- 数据元素及其关系在计算机存储器中的结构
- 是数据结构在计算机中的表示
逻辑结构与存储结构的关系:
- 存储结构是逻辑关系的映像与元素本身的映像
逻辑结构的种类
划分方法一:
-
线性结构: 有且仅有一个开始和终端节点,并且所有节点都最多只有一个直接前趋和一个直接后继.
例如: 线性表, 栈, 队列, 串
2 非线性结构:一个结点可能有多个直接前趋和直接后继
例如: 树, 图
划分方式二 四类基本逻辑结构
-
集合结构 : 结构中的数据元素之间除了同属于一个集合的关系外,无其他任何关系
-
线性结构: 结构中的数据元素之间存在着一对一的线性关系
-
树形结构: 结构中的数据元素之间存在着一对多的层次关系
-
图形结构或者网状结构: 结构中的数据元素之间存在着多对多的任意关系
四种基本的存储结构
顺序存储结构:
- 用一组连续的存储单元一次存储一次存储数据元素, 数据元素之间的逻辑关系由元素的 存储位置来表示
- C语言中用数组来实现顺序存储结构
链式存储结构
-
用一组任意的存储单元存储数据元素,数据元素之间的逻辑关系用指针来表示
-
c语言中用指针来实现链式存储结构
索引储存结构
- 在存储结点信息的同时, 还建立附加的索引表
散列存储结构
- 根据结点的关键字直接计算出该结点的存储地址
1.1.3 数据类型和抽象数据类型
- 在使用高级程序设计语言编写程序的时候,必须明确他们所属的数据类型
- 高级语言中的数据类型明显的规定了在程序执行期间变量和表达的所有可能的取值范围,以及在这些数值范围上所允许进行的操作
数据类型的作用:
- 约束变量或者常量的取值范围
- 约束变量或常量的操作
数据类型:
- 定义:数据类型是一组性质相同的值的集合以及定义于这个值集合上的一组操作的总称
抽象数据类型(Abstract Data Type,ADT)
- 定义:是指一个数学模型以及定义在此数学模型上的一组操作
-
由用户定义,从问题抽象出**数据模型**(逻辑结构)
- 还包括定义在数据模型上的一组抽象运算(相关操作)
- 不考虑储存结构和具体实现算法
-
抽象数据类型的形式定义
一个抽象数据类型的定义格式:
基本操作定义格式说明:
- 参数表: 赋值参数: 只为操作提供输入值 引用参数 以&打头,除可提供输入值外,还将返回结果
- 初始条件: 描述操作执行之前数据结构和参数应满足的条件
- 操作结果: 说明操作正常完成之后,数据结构的变化状况和应返回的结果
举例: 圆Circle定义
ADT Circle{
数据对象: D ={r,x,y|r,x,y均是实数}
数据关系: R={<r,x,y>|r是半径,<x,y>是圆心的坐标}
基本操作:
Circle(%C,r,x,y)
操作结果:构造一个圆
double Area(C)
初始条件:圆以存在
操作结果: 计算面积
} ADT Circle
1.2 抽象数据类型的表示与实现
学习过程中,我们使用类C语言(介于伪代码和C语言之间)作为描述工具
举例: 抽象数据类型复数的实现
typedef struct{
float realpart; /* 实部 */
float imagpart; /* 虚部 */
}Complex
/* 如果函数出现在被调用函数之后,就要声明 */
void assign(Complex *A,float real,float imag);
void add(Complex *A,Complex B,Complex C);
void minus(Complex *A,Complex B,Complex C);
void multiply(Complex *A,Complex B,Complex C);
void divide(Complex *A,Complex B,Complex C);
void assign(Complex *A,float real,float imag){
A->realpart = real;
A->imagepart = imag;
}
void add(Complex *A,Complex B,Complex C){
A->realpart = B.realpart + C.realpart;
A->imagpart = B.imagpart + C.imagpart;
}
..
1.3 算法与算法分析
算法的定义
- 对特定问题求解方法和步骤的一种描述,他是指令的有限序列.其中每个指令表示一个或多个操作
算法的描述
- 自然语言: 中文,英语
- 流程图
- 伪代码:类语言:类C语言(课程用这个来描述)
- 程序代码
算法与程序
- 算法是解决问题的**一种方法或者一个过程,**考虑如何将输入转换成输出,一个问题可以有多种算法
- 程序是用某种程序设计语言对算法的具体实现.(程序 = 数据结构 + 算法)
算法特性
- 有穷性: 一个算法必须在执行有穷步骤之后结束
- 确定性: 算法中的每一条指令必须要有确定的含义,对于相同的输入,必然要有相同的输出
- 可行性: 算法是可执行的
- 输入:一个算法有零个或者多个输入
- 输出: 算法必须要有一个或者多个输出
算法的要求
- 正确性(不含语法错误,输入刁难的输入的合法数据没问题)
- 可读性(应该易于人理解,尽量不要用if else)
- 健壮性(输入非法数据时,算法应该处理出错,而不应该时中断程序的执行,而应该时表示出错的原因)
- 高效性(尽量少的时间和尽量低的存储)
算法效率
-
重要的是算法的效率,前面三点是好算法的前提
-
时间效率:值得是算法所要消耗的时间
-
空间效率: 值得是算法执行过程中所要耗费的存储空间
-
算法时间效率的度量
- 用算法编制一个程序用所消耗的时间来度量
- 事后统计: 顾名思义
- 事前分析: 用算法复杂度来测算
事前分析方法
- 算法运行时间 = 一个简单操作所需时间 * 简单操作的次数
我们假设把每条语句执行所需的时间均为单位时间
时间复杂度
若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数.记作 T(n) = O(f(n))
称O(f(n))为算法的渐进时间复杂度,简称为时间复杂度
算法中基本语句重复执行次数是问题规模的某个函数f(n),算法的时间量度记作: T(n) = O(f(n))
定理1.1 (体现出增长率的含义)
分析算法时间复杂度的基本方法
- 找出语句频度最大的那条语句作为基本语句
- 计算基本语句的频度得到问题规模n的某个函数f(n)
- 取其数量级用符号"O"来表示
难一些的题目举例
int i =1;
while(i<=n)
i =i*2;
我们要考虑(通常考虑最坏时间复杂度)
-
最坏时间复杂度:指在最坏的情况下,算法的时间复杂度
-
平均时间复杂度: 指在所有可能输入实例在等概率出现的情况下,算法的期望运行时间
-
最好时间复杂度: 指在最好的情况下,算法的时间复杂度.
-
对于复杂的算法,我们将其分成几个部分,然后利用大O的加法规则和乘法规则来计算时间复杂度
算法效率的比较
- 当n取的很大的时候,指数时间算法和多项式时间算法在所需时间上非常悬殊
空间复杂度
-
空间复杂度:算法所储存空间的度量,
- 记作: S(n ) = O(f(n))
-
算法索要占据的空间
- 算法本身要占据的空间,输入\输出,指令,常数,变量等
- 算法要使用的辅助空间
例子:
抽象数据类型 = 数据类型的逻辑结构 + 抽象运算
- 逻辑结构的实现又可以由多种存储结构来实现, 每种存储结构又有多种算法,因此我们需要算法分析