基本概念
数据结构是一门讨论“描述现实世界实体的数学模型(非数值计算)及其上的操作在计算机中如何表示和实现”的学科。
数据对信息的一种符号表示。在计算机中指能输入并被计算机程序处理的符号的总称。
数据元素数据的基本单位。通常被作为一个整体来考虑和处理。由若干数据项组成。数据项是数据不可分割的最小单位。
数据对象性质相同的数据元素的集合。是数据的一个子集。
什么是数据结构?
“结构”指数据元素之间的关系。
数据结构即相互之间存在某种逻辑关系的数据元素的集合。
形式定义描述:一个二元组。
Data_Structrues=(D,S)
D:数据元素的有限集,
S:D上关系的有限集。
数据结构类型(从关系和结构方面划分)
1.线性结构
2.树形结构
3.图状结构
4.集合结构
数据结构层次
逻辑结构 数据元素之间的逻辑关系,可用一个数据元素的集合和定义在上面集合上的若干关系表示。
物理结构 即存储结构,是数据结构在计算机中的表示和实现。
数据的存储结构
逻辑结构在存储器中的映像
“数据元素的映象”?
方法:用二进制位(bit)的位串表示数据元素
eg:(321)10 = (501)8 = (101000001)2
A = (101)8 = (001000001)2
(括号外面的是下标啦,我不知道怎么打下标上去,表示几进制)
“关系的映像”?
1,顺序映像 以相对位置表示后继关系
eg:令y的存储位置和x的存储位置之间相差一个常量C,而C是一个隐含值,整个存储结构中只包含数据元素本身的信息。即 | x | | y |。
2,链式映像 以附加信息(指针表示后继关系)
需要用一个和x在一起的附加消息(指针)指示y的存储位置。
即:| y | | x |(/**这个地方有一个x指向y的箭头,我实在不知道怎么弄,看不懂这个编辑器/*)
索引存储方式
除数据元素存储在一地址连续的内存空间外,还需建立一个索引表,兼有静态和动态特性。
散列存储方式
通过散列函数和解决冲突的方法,将关键字散列在连续的有限的地址空间内,并将散列函数的值解释成关键字所在元素的的存储地址。
特点是:存取速度快,只能按关键字随机存取,不能顺序存取,也不能折半存取。
数据类型
在一种程序设计语言中,变量所具有的数据种类。
例如:C语言中数据类型:
基本类型:整形、浮点型、字符型、指针、枚举型
构造类型:数组、结构、联合
数据对象:某种数据元素的集合。数据对象可以是有限的,也可以是无限的。
eg:整数的数据对象{…6,-2,-1,0,1,2,…}
英文字符类型的数据对象是{…A,B,C,D,…}
***数据结构***既要描述数据类型的数据对象也要描述数据对象各元素之间的相互关系。
抽象数据类型
一个数学模型以及定义在该模型上的一组操作。
/*实际上就是对该数据结构的定义。因为它定义了一个数据的逻辑结构以及再次结构上的一组算法。
三元组表示(D,S,P)
抽象数据类型的表示和实现
定义ADT:
ADT<ADT名>
{数据对象:<数据对象的定义>
结构关系:<结构关系的定义>
基本操作:<基本操作的定义>
}ADT<ADT名>
注:数据对象和结构关系的定义采用数学符号和自然语言描述。
操作的基本格式定义为:
<操作名称>(参数表)
操作前提:<操作前提描述>
操作结果:<操作结果描述>
算法和算法分析
***算法***对特定问题求解步骤的一种描述。是指令的有限序列,每一条指令表示一个或多个操作。
特性:(1)有穷性,(2)确定性,(3)可行性,(4)输入,(5)输出
算法的设计要求
一,评价好算法的标准:
1,正确性(Correctness)
2,可读性(Readability)
3,健壮性(Robustness)
4,效率与存储量要求:
效率 算法执行时间
存储量需求 算法执行过程中所需要的最大存储空间。
(一般,这二者与问题的规模有关。)
算法效率的衡量方法和准则
两种衡量方法:
1,事后统计法
缺点:1,必须执行程序 2,其他因素掩盖算法本质。
2,事前分析估算法
影响算法执行时间的相关因素
1,算法选用的策略
2,问题的规模
3,编写程序的语言
4,编译程序产生的机器代码的质量
5,计算机执行指令的速度
一个特定算法的“运行工作量”的大小,只依赖于问题的规模(通常用整数量n表示),或者说它是问题规模的函数。
eg: 假如,随着问题规模n的增长,算法执行时间的增长率和f(n)的增长率相同,
则表示为:
T(n)=O(f(n)) 称T(n)为算法的(渐近)时间复杂度。
如何估算时间复杂度?
算法=控制结构+原操作(固有数据类型的操作)
算法执行时间=(原操作(i)的执行次数*原操作(i)的执行时间)i项求和
算法执行时间与原操作执行次数之和成正比
算法运行时间的衡量准则:
选取对于问题来说是基操的原操作,以该基本操作在算法中的重复执行的次数作为算法运行时间的衡量准则。
eg1:
for (j = 1; j <= n; ++j)
{
c[I][j] = 0;
for (k = 1; k <= n; ++k)
c[I][j] += a[I][k] * b[k][j];
}
由于该代码是一个三重循环,每个循环从1到n,则总次数为:nnn=n^3``
时间复杂度为T(n)=O(n^3)
*
频度*:指该语句重复执行的次数
eg2:{++x;s=0;}
将x自增看成是基本操作,则语句频度为1,即时间复杂度为O(1)
若将s=0看作基本操作,其时间复杂度仍为O(1),即常量阶。
eg3:
for (I = 1; I <= n; ++I)
for (j = 1; j <= n; ++j)
{
++x; s += x;
}
语句频度为2n;时间复杂度为O(n),即时间复杂度为线行阶。
eg4:
for(I=1;I<=n;++I)
for(j=1;j<=n;++j)
{++x;s+=x;}
语句频度为:2n^2
时间复杂度为:O(n^2),即时间复杂度为平方阶。
eg5:
for(i=2;i<=n;++i)
for(j=2;j<=i-1;++j)
{++x;a[i,j]=x;}
语句频度为:1+2+3+…+n-2=(1+n-2) ×(n-2)/2
=(n-1)(n-2)/2
=n^2-3n+2
所以,时间复杂度为O(n^2),即此算法的时间复杂度为平方阶。
**
算法的存储空间需求
表示随着问题规模 n 的增大,算法运行所需存储量的增长率与 g(n) 的增长率相同。
算法的空间复杂度定义为:S(n) = O(g(n))
算法的存储量包括:
1.输入数据所占空间;
2.程序本身所占空间;
3.辅助变量所占空间。
若输入数据所占空间只取决与问题本身,和算法无关,则只需要分析除输入和程序之外的辅助变量所占额外空间。
若所需额外空间相对于输入数据量来说是常数,则称此算法为原地工作。
若所需存储量依赖于特定的输入,则通常按最坏情况考虑。