数据结构01 绪论
文章目录
01.1 数据结构的研究内容
程序=算法+数据结构
数据结构主要研究内容为:研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和操作。
01.2基本概念及术语
01.2.1基本术语
术语 | 概念 | 举例 |
---|---|---|
数据(Data) | 所有能输入到计算机中去的描述客观事物的符号。分为数值性数据和非数值性数据(多媒体信息处理)。 | 数学计算中遇到的整数和实数,文本编辑中用到的字符串等。 |
数据元素(Data Element) | 数据的基本单位,也称结点(node)或记录(record)。 | 用于完整的描述一个对象,如学生成绩表中一名学生的记录。 |
数据项(Data Item) | 是组成数据元素的,有独立含义的、不可分割的最小单位也称域(field)。 | 如学生的姓名,性别,学号等。 |
数据对象(Data Object) | 是性质相同的数据元素的集合,是数据的一个子集。 | 整数数据对象N={0,1,2…} |
数据结构(Data Structure) | 是相互之间存在一种或多种特定关系的数据元素的集合,数据结构是带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系 |
PS:数据、数据元素、数据项三者之间的关系
数据>数据元素>数据项
例:学生成绩表>个人成绩记录>学号、姓名…
01.2.2数据结构的层次划分
数据结构的两个层次
1. 逻辑结构:数据元素之间抽象化的相互关系,与数据的存储无关,独立于计算机,它是从具体问题抽象出来的数据模型。
a. 线性结构:有且仅有一个开始和一个终端结点,并且所有结点都最多只有一个直接前趋和一个后继。数据元素间存在一个对一个的关系。
* 线性表
* 栈和队列
* 字符串
b. 非线性结构:一个结点可能有多个直接前趋和直接后继。
* 集合结构:除了“属于同一集合”的关系外,别无其他关系。
* 树结构:数据元素间存在一对多的关系
* 图结构:数据元素之间存在多个对多个的关系。
2. 存储结构(物理结构):数据元素及其关系再计算机存储器中的存储方式。
a. 顺序存储结构:借助元素在存储器中的相对位置来表示数据元素间的逻辑关系。
b. 链式存储结构:借助指示元素存储地址的指针表示数据元素间的逻辑关系。
01.3抽象数据类型的表示与实现
01.3.1 数据类型(Data Type)
定义:在一种程序语言中,变量所具有的数据种类。
FORTRAN语言:
整型、实型和复数型
C语言:
基本数据类型:char int float double void。
构造数据类型:数组、结构体、共用体、文件。
数据类型是一组性质相同的值的集合,以及定义与这个集合上的一组操作(运算)的总称。
01.3.2 抽象数据类型(ADTs:Abstract Data Types)
更高层次的数据抽象。(线性表、栈、队列、树、图)
由用户定义,用以表示应用问题的数据模型。
由基本的数据类型组成,并包括一组相关的操作。
抽象数据类型可以用以下的三元组来表示:
ADT=(D,S,P)
D:数据对象
S:D上的关系集
P:D上的操作集
ADT常用定义格式
ADT抽象数据类型名
{
数据对象:<数据对象的定义>
数据关系:<数据关系的定义>
基本操作:<基本操作的定义>
}ADT抽象数据类型名
01.3.3 信息隐蔽和数据封装,使用与实现相分离
01.3.4 抽象数据类型的表示与实现
抽象数据类型可以通过固有的数据类型(如整型、实型、字符型等)来表示和实现。
它有些操作类似C语言中的结构(struct)类型,但增加了相关的操作。
上述语言使用的是类C语言(介于伪代码和C语言之间)作为描述工具。
01.4算法与算法分析
01.4.1 算法概述
算法的定义:是对特定问题求解步骤的一种描述,是指令的有限序列。
算法的描述:自然语言、流程图、程序设计语言、伪代码
算法的特性:
1. 有穷性:算法应在执行有穷步后结束
2. 确定性:每步指令都是确切、无歧义的
3. 可行性:每一条操作都可以通过基本运算来实现
4. 输入:有零个或多个输入
5. 输出:有一个或多个输出(处理结果)
设计算法应考虑以下目标:
1. 正确性:在合理的数据输入下,能够在有限的运行时间内得到正确的结果。
2. 可读性:便于人们理解和相互交流,便于调试和修改。
3. 健壮性:当输入非法时,适当的做出正确反应或进行相应的处理。
4. 高效性:效率和低储存需求。
01.4.2时间复杂度
算法效率:用依据该算法编制的程序在计算机上执行所消耗的时间来度量。
1. 事后统计:
利用计算机内部的计时功能,不同算法的程序可以用一组或多组相同的统计数据区分。
缺点:
必须先运行依据算法编制的程序。
所的时间统计量依赖于硬件、软件等环境因素,掩盖算法本身的优劣。
2. 事前分析估算:
一个高级语言程序在计算机上运行所消耗的时间取决于:
1. 依据的算法选用何种策略
2. 问题的规模
3. 程序的编程语言
4. 编译程序所产生的机器代码质量
5. 机器执行指令的速度
同一个算法用不同语言、不同的编程程序,在不同的计算机上运行,效率均不同。————使用绝对时间单位衡量算法效率不合适。
01.4.3 时间复杂度的渐进表示法
算法中基本语句重复执行的次数是问题规模n的某个函数f(n),算法的时间量度记作:T(n)=O(f(n))
表示随着n的增大,算法执行的时间的增长率和f(n)的增长率相同,称渐进时间复杂度,简称时间复杂度。
基本语句重复执行次数
* 算法中重复执行次数和算法的执行时间成正比的语句。
* 对算法运行时间的贡献最大。
n越大算法的执行时间越长
* 排序:n为记录数
* 矩阵:n为矩阵阶数
* 多项式:n为多项式的项数
* 集合:n为元素个数
* 树:n为树的结点个数
* 图:n为图的顶点数或边数
例01.4.3-1:
//n*n阶矩阵加法
for(i=0;i<n;i++)
for(j=0;j<n;j++)
c[i][j]=a[i][j]+b[i][j];
语句的频度(Frequency Count):重复执行的次数:n*n; T ( n ) = O ( n 2 ) T(n)=O(n^2) T(n)=O(n2)
01.4.4 分析算法时间复杂度的基本方法
- 找出语句频度最大的那条语句作为基本语句
- 计算基本语句的频度得到问题规模n的某个函数 f ( n ) f(n) f(n)
- 取其数量级用符号“O”表示
例01.4.4-1
void exam(float x[][],int m,int n)
{
float sum[];
for(int i=0;i<m;i++)
{
sum[i]=0.0;
for(int j=0;j<n;j++)
sum[i]+=x[i][j];
}
for(i=0;i<m;i++)
cout<<i<<":"<<sum[i]<<endll;
}
基本语句:sum[i]+=x[i][j];
$
f(n)=n\times m
$
$
T(n)=O(f(n))=O(m\times n)
$
01.4.5 空间复杂度
空间复杂度:算法所需储存空间的度量,
记作:
S
(
n
)
=
O
(
f
(
n
)
)
S(n)=O(f(n))
S(n)=O(f(n))
其中n为问题的规模(或大小)
算法占据的空间:
* 算法本身要占据的空间,输入/输出,指令,常数,变量等
* 算法要使用的辅助空间
01.4.6 渐进空间复杂度
例01.4.6-1
//算法1 原地算法S(n)=O(1)
for(i=0;i<n/2;i++)
{
t=a[i];
a[i]=a[n-i-1];
a[n-i-1]=t;
}
//算法2 辅助空间S(n)=O(n)
for(i=0;i<n;i++)
b[i]=a[n-i-1];
for(i=0;i<n;i++)
a[i]=b[i];
算法一:仅需要借助一个变量t,与问题规模n大小无关,所以其空间复杂度为
O
(
1
)
O(1)
O(1)
算法二:需要另外借助一个大小为n的辅助数组b,所以其空间复杂度为
O
(
n
)
O(n)
O(n)
对于一个算法,其时间复杂度和空间复杂度往往是相互影响的,当追求一个较好的时间复杂度时,可能会导致占用较多的储存空间,即可能会使空间复杂度的性能变差,反之亦然。通常情况下,鉴于运算空间较为充足,人们都以算法的时间复杂度作为算法优劣的衡量指标。
##01.5 错题集
- 以下说法正确的是()
A. 数据元素是数据的最小单位
B. 数据项是数据的基本单位
C. 数据结构是带有结构的各数据项的集合
D. 一些表面上很不相同的数据可以有相同的逻辑结构
解析(D)
A. 数据元素是数据的基本单位。
B. 数据项是数据的最小单位。
C. 数据结构是带“结构”的数据元素的集合
D. 正确
- 通常要求同一逻辑结构中的所有数据元素具有相同的特性,这意味着()
A. 数据具有同一特点
B. 不仅数据元素所包含的数据项个数要相同,而且对应数据项的类型要一致
C. 每个数据元素都一样
D. 数据元素所包含的数据项个数要相等
解析(B)
- 某算法的语句执行频度为
(
3
n
+
n
l
o
g
2
n
+
n
2
+
8
)
(3n+nlog_2n+n^2+8)
(3n+nlog2n+n2+8),其时间复杂度表示()
A. O ( n ) O(n) O(n)
B. O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)
C. O ( n 2 ) O(n^2) O(n2)
D. O ( l o g 2 n ) O(log_2n) O(log2n)
解析(C)
- 以下程序中语句“x++;”的语句频度为()
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
for(k=1;k<=j;k++)
x++;
A.
n
(
n
+
1
)
(
2
n
+
1
)
2
\frac{n(n+1)(2n+1)}{2}
2n(n+1)(2n+1)
B.
n
(
n
+
1
)
(
n
+
1
)
2
\frac{n(n+1)(n+1)}{2}
2n(n+1)(n+1)
C.
n
(
n
+
1
)
(
2
n
+
1
)
6
\frac{n(n+1)(2n+1)}{6}
6n(n+1)(2n+1)
D.
n
(
n
+
1
)
(
n
+
2
)
6
\frac{n(n+1)(n+2)}{6}
6n(n+1)(n+2)
解析(D)
∑
i
=
1
n
∑
j
=
1
i
∑
k
=
1
j
1
\sum_{i=1}^{n}\sum_{j=1}^{i}\sum_{k=1}^{j}1
∑i=1n∑j=1i∑k=1j1
=
∑
i
=
1
n
∑
j
=
1
i
j
=\sum_{i=1}^{n}\sum_{j=1}^{i}j
=∑i=1n∑j=1ij
=
∑
i
=
1
n
i
(
i
+
1
)
2
=\sum_{i=1}^{n}\frac{i(i+1)}{2}
=∑i=1n2i(i+1)
=
1
2
(
∑
i
=
1
n
i
2
+
∑
i
=
1
n
i
)
=\frac{1}{2}(\sum_{i=1}^{n}i^2+\sum_{i=1}^{n}i)
=21(∑i=1ni2+∑i=1ni)
=
1
2
(
n
(
n
+
1
)
(
2
n
+
1
)
6
+
n
(
n
+
1
)
2
)
=\frac{1}{2}(\frac{n(n+1)(2n+1)}{6}+\frac{n(n+1)}{2})
=21(6n(n+1)(2n+1)+2n(n+1))
=
n
(
n
+
1
)
(
n
+
2
)
6
=\frac{n(n+1)(n+2)}{6}
=6n(n+1)(n+2)
- 下面说法错误的是()。
(1) 算法原地工作的含义是指不需要任何额外的辅助空间
(2) 在相同的规模下n下,复杂度 O ( n ) O(n) O(n)的算法在时间上总是优于复杂度 O ( 2 n ) O(2^n) O(2n)
(3) 所谓时间复杂度是指最坏情况下,估算算法执行时间的一个上界
(4) 某算法的时间复杂度为 O ( n 2 ) O(n^2) O(n2),表明该算法的时间与 n 2 n^2 n2成正比
A. (1)
B. (1),(2)
C. (1),(4)
D. (3)
解析(A)
原地算法指算法执行时所需要的辅助空间,其相对于输入量而言是个常数。故(1)错误。
- 设该数据结构A=(D,R),其中D={1,2,3,4},R={r},r={<1,2>,<2,3>,< 3,4>,<4,1>},则该数据结构A是()
A. 线性结构
B. 树结构
C. 图
D. 集合
解析(C)
数据元素间存在多对多的关系。