一、数据结构的基本概念
数据结构是一门研究非数值计算的程序设计中计算机的操作对象以及他们之间关系的一门学科。(描述非数值计算问题的数学模型不是数学方程,而是具有逻辑关系的数据)
【数据的基本概念】
- 数据: 一种能输入计算机且能被计算机处理的各种符号的集合。
- 数据元素:组成数据的基本单位,在计算机程序中通常作为一个整体进行考虑或处理。(又称为元素,记录,节点或顶点)
- 数据项:构成数据元素的不可分割的最小单位。
- 数据>数据元素>数据项
- 数据对象:具有相同性质的数据元素的集合,是数据的一个子集。(e.g:整数的数据对象是 集合N={0,±1,±2...})
- 数据元素不是孤立存在的,他们之间存在某种关系,数据元素相互之间的关系成为结构。
- 数据结构是指带结构的数据元素的集合。(数据结构的定义)
- 数据结构表示了数据元素之间的逻辑关系,数据元素及其关系在计算机内存中的表示,数据的运算和实现等。
- 逻辑结构:逻辑结构是描述数据结构之间的逻辑关系,是独立于计算机,是从具体问题中抽象的数学模型。
- 存储结构:存储结构是数据元素及其关系在计算机存储器中的结构(表示方式)
- 【数据类型】
- 在使用高级程序设计语言编写程序时,必须对程序中出现的每个变量,常量或表达式明确说明它们所属的数据类型。
- 一些最基本的数据结构可以通过数据类型来实现。(e.g:数组,字符串),但对于复杂的数据结构,如栈,队列,树等,则不能通过数据类型来实现。
- 数据类型的作用: 1)约束常量或变量的取值范围。 2)约束常量或变量的操作。
- 数据类型的定义(Data Type): 数据类型是一组性质相同的值的集合以及定义于这个值的集合上的一组操作的总称。
- 数据类型=值的集合+值集合上的一组操作
- 抽象数据类型(ADT):是指一个数学模型以及定义在此数学模型上的一组操作。
- 形式定义:D+S+P。(D:数据对象,S:D上的关系集,P:对D的基本操作集)
- 定义格式:
ADT 抽象数据类型名{
数据对象:<数据对象的定义> // 用伪代码描述
数据关系:<数据关系的定义> //用伪代码描述
基本操作:<基本操作的定义> //定义格式:基本操作名(参数表)+初始条件+操作结果
}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 )
}
二、算法的基本概念
1.定义:算法是规则的有限集合,是为解决特定问题而规定的一系列操作。
2.算法的特性:
1)有限性:有限步骤之内正常结束,不能形成无穷循环。
2)确定性:每一个步骤必须有确定含义,无二义性。
3)可行性:原则上能实现。
4)输入:有多个或0个输入。
5)输出:至少有一个或多个输出。
3.算法设计要求:正确性、可读性、健壮性(鲁棒性)[出现异常情况会正确处理]、高效率低存储
【注意】正确性层次:
1)对于几组输入数据能够得出满足要求的结果;
2)对于精心选择的典型、苛刻而带有刁难性的几组输入数据能够得出满足要求的结果;
3)对于一切合法的输入数据都能产生满足要求的结果
4.算法的描述方式
1)自然语言:通俗易懂,容易掌握;但不够严谨、容易有二义性。
2)框图(流程图或N-S图):重处理流程,便于检查修改;但无法表达数据流程。
3)伪代码(类语言):结构性较强,比较容易书写和理解,修改起来也方便。
4)高级语言:严谨、准确;细节过多。
5.对算法进行性能评价
a.评价一个算法主要看这个算法所占用机器资源(时间、空间)的多少。
时间——算法从开始到结束所耗费时间。 空间——算法执行过程中所占存储量。
注意:时间效率与空间效率有时候是矛盾的
b. 算法时间效率的度量方法
事后统计: 将算法实现,测量其时间和空间开销。(缺点:需要消耗相应的时间和精力)
事前分析:对算法所消耗资源的一种估算方法。(找出要执行操作所需要的时间与次数进行乘积)
e.g:nxn矩阵相乘算法
for(i=1;i<=n;i++){ //n+1次
for(j=1;j<=n;j++){ //n(n+1)次
c[i][j]=0; //n*n次
for(k=0;k<n;k++){ //n*n*(n+1)次
c[i][j]=c[i][j]+a[i][k]*b[k][j]; //n*n*n次
}
}
}
c.算法的时间复杂度的渐进表示法:对于两个不同算法的时间效率,仅仅比较它们的数量级。
一般情况下,我们只考虑算法中基本操作的执行次数,它是问题规模n的某个函数,用T(n)表示。
例:将一维数组a中的n个数逆序存放到原数组中。
算法一: 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;
}
算法二: 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];
}