数据结构研究内容
研究非数值计算的程序设计中计算机的操作对象以及之间关系和操作的学科
使用计算机解决实际问题首先要抽象出一个数学模型然后设计算法。
基本概念和定义
数据
能输入计算机且能被处理的各种符号的集合
-
信息的载体
-
客观事物的符号化表示
-
能够被计算机识别,存储和加工
包括
-
数值型数据
-
非数值型数据
数据元素
数据的基本单位,通常作为一个整体进行考虑和处理
简称为元素,也被称为记录,节点或顶点。
可以由若干个数据项组成
数据项
构成数据元素的不可分割的最小单位
数据>数据元素>数据项 eg:学生表>个人信息>学号,姓名...
数据对象
性质相同的数据元素的集合,是数据的子集
例如: 整数的数据对象:N={0,±1,±2..}
数据元素和数据对象
- 数据元素——组成数据的基本单位
- 数据对象——性质相同的数据元素的集合
例如一个班内学生管理系统,整个班级是数据对象,每个学生是数据元素,学生的信息就是数据项
两张表的情况:来自 blog.csdn.net/qq_31442743… 的辨析
数据结构
- 数据元素互相之间的关系称为结构
- 相互之间存在一种或多种特定关系的数据元素的集合
分为三部分:逻辑结构,存储结构,运算集合
包含
- 数据元素之间的关系,称为逻辑结构
- 数据元素及其关系在计算机内存中的表示(映像),称为物理结构/存储结构
- 数据的运算和实现,对数据元素施加的操作以及操作在相应存储结构上的实现
逻辑结构和存储结构的关系
- 存储机构是逻辑关系的映像与元素本身的映像
- 逻辑结构是数据结构的抽象,存储结构是数据结构的 实现
逻辑结构的种类
- 线性结构:线性表,栈,队列,串
- 非线性结构:树,图
- 四种基本逻辑结构:集合,线性,树,图
集合:除了同属于一个集合,无任何其他关系
线性:一对一
树形:一对多
图形:多对多
存储结构
- 顺序存储结构
- 链式存储结构
- 索引存储结构
- 散列存储结构
顺序存储结构
用一组连续的存储单元依次存储数据,数据元素之间的逻辑关系有元素存储位置表示(常用数据实现)
链式存储结构
用任意存储单元存储数据,用指针表示(常用指针实现)
索引存储结构
储存结点信息的同时,建立附加的索引表
散列存储 根据结点的关键字直接计算出该结点你的存储地址
数据类型
定义:一组性质相同的值的集合以及定义于这个值集合的一组操作的总称
数据类型=值的集合+值集合上的一组操作
作用:约束变量取值范围及操作
抽象数据类型ADT
其实就可以看做是另一种方法描述数据类型
指一个数学模型以及定义在此数学模型上的一组操作
包括以下三个方面:
- 数据对象(一个圆)
- 数据关系(半径和原点)
- 基本操作(构造圆,求面积,求周长...类似函数)
ADT定义的格式:
ADT<ADT名>
{数据对象:
结构关系:
基本操作:
}ADT <ADT名>
- 数据对象的定义应该在已有数据类型或定义数据类型基础上定义新对象
- 数据对象和结构关系的定义采用数学符号和自然语言
- 基本操作做定义包括:操作名称、参数表、初始条件、操作结果 4.基本操作的定义格式:
<操作名称>(参数表)
操作前提:<操作前提描述>
操作结果:<操作结果描述>
例子1:
例子2:
抽象数据类型的形式定义
此处为离散数学相关:
算法和算法分析
对于复杂的算法,将其分为几个容易估算的部分,然后利用O的加法法则和乘法法则计算时间复杂度
语句频度
指语句在一个算法中重复执行的次数
其中,最外层循环仅执行n次,内一层循环执行n²,再内一层循环是n³
结构化程序设计
任何程序都可由顺序,选择,重复三种基本控制结构组成
设计方法:
- “自顶向下,逐步求精”的设计思想
- “独立功能,一个入口,一个出口”的模块化结构
- “仅用三种基本控制结构”的设计原则
算法描述规范与设计风格
函数结果的带出方式:函数结果共有全程量、函数返回值、传址参数三种带出方式
参数传递当时主要有传值和传地址
全程变量方法
全程量实际是一个隐含的接口
int fun1(int a[] ,int n)
{ int i,max;
max=min=a[0];//min是函数外的全局变量
for(i=0,i<n,i++){
if(a[i]>max)
max=a[i];
if(a[i]<min)
min=a[i]; //对全局变量赋值,也就相当于返回了
}
return max; //返回max
}
数组方法
多个同类型的数据放在一个数组里面用指针传出
int *fun2(int a[] ,int n)
{ static int b[2];
int i;
b[0]=b[1]=a[0];//第一个存最大数
for(i=0,i<n,i++){
if(a[i]>b[0])
b[0]=a[i];
if(a[i]<b[1])
b[1]=a[i];
}
return b; //返回指针的函数,仅返回数组名
}
结构体方法
多个不同类型的数据放在一个全局结构体
int *fun3(int a[] ,int n)
{ Data *p;//声明一个结构体指针p
int i;
p=(Data *) malloc(sizeof(Data *));//分配一个内存大小为Data大小的空间
p->max=p->min=a[0];
for(i=0,i<n,i++){
if(a[i]>p->max)
p->max=a[i];
if(a[i]<p->min)
p->min=a[i];
}
return p; //返回结构体(一个内容丰富的结点)
}
指针方法
将需要返回的内容用指针返回
int *fun4(int a[] ,int n, int *p ,int *q)
{ int i;
*p=*q=a[0];
for(i=0,i<n,i++){
if(a[i]>*p)
*p=a[i];
if(a[i]<*q)
*q=a[i];
}
}
时间复杂度
以语句频度刻画随问题规模n增加的函数f(n)执行时间量度
T(n)=O(f(n))
复杂度取最高数量级,比如2n³+n²,时间复杂度就是n³
最坏时间复杂度:在最坏情况下基本操作时间上限。
两大规则
- 加法规则:
不嵌套的两个部分,取最大的
- 乘法规则
嵌套的两个部分,取乘积
时间复杂度比较
递增顺序
| 常数阶 | 对数阶 | 线性阶 | 线型对数阶 | 平方阶 | 立方阶 | --- | K次方阶 | 指数阶 |
|---|---|---|---|---|---|---|---|---|
| O(1) | O(log2n) | O(n) | O(nlog2n) | O(n²) | O(n³) | ... | O(n的k次方) | O(2的n次方) |
| 对数阶------>指数爆炸 |
空间复杂度
算法所需存储空间的度量(一般不考虑)
S(n)=O(f(n))
例子:
临时变量大小为1,空间复杂度S(n)=O(1)
需要n个大小的数组,空间复杂度S(n)=O(n)
摘自 青岛大学王卓老师:www.bilibili.com/read/cv3285…
摘自 西安邮电大学王曙燕老师:www.icourse163.org/learn/XIYOU…