数据结构绪论

数据结构:问题的数学模型,是指互相之间存在着一种或多种特定关系的数据元素的集合

算法:求解问题的策略,操作步骤

物理(存储)结构:数据结构在计算机中的表示

设计数据结构的存储结构时要存放所有数据元素的值和他们之间的逻辑关系

2种存储结构:

顺序存储映像—顺序存储结构借助数据元素在存储器中的相对位置来表示数据元素之间的逻辑关系

非顺序存储映像—链式存储结构借助指示数据元素存储地址的指针来表示数据元素之间的逻辑关系

抽象数据类型(Abstract Data Type 简称ADT) :是指一个数学模型以及定义在此数学模型上的一组操作。 

(D, R, P)三元组表示 :

       D是数据对象 

       R是D上的关系的集合 

       P是D上的操作的集合

定义格式:

ADT抽象数据类型名 

   {  数据对象:〈数据对象的定义〉

      数据关系:〈数据关系的定义〉 

      基本操作:〈基本操作的定义〉 

   } ADT抽象数据类型名 

eg:

ADT Complex
{ 数据对象:D={e1,e2|e1,e2∈RealSet}
数据关系:R1={ (e1,e2)| e1是实数部分 , e2 是复数的虚数部分 }
基本操作:
AssignComplex( &Z, v1, v2 )
操作结果:构造复数 Z,其实部和虚部 分别被赋以参数 v1 和 v2 的值。
DestroyComplex( &Z)
操作结果:复数Z被销毁。
GetReal( Z, &realPart )
初始条件:复数已存在。
操作结果:用realPart返回复数Z的实部值。
GetImag( Z, &ImagPart )
初始条件:复数已存在。
操作结果:用ImagPart返回复数Z的虚部值。
Add( z1,z2, &sum )
初始条件:z1, z2是复数。
操作结果:用sum返回两个复数z1, z2 的 和值。
} ADT Complex
假设:z1和z2是上述定义的复数 ,则 Add(z1, z2, z3) 操作的结果即为z3 = z1 + z2

抽象数据类型的表示和实现

抽象数据类型需要通过固有数据类型(高级编程语言中已实现的数据类型)来实现。

//存储结构的定义
typedef struct{
float el;
float e2;
}complex;

//基本操作函数

// 构造复数 Z,其实部和虚部分别被赋以参数 // z1 和 z2 的值
void Assign(complex &z, float v1,folat v2);

//返回复数z实部值
float GetReal(complex z);

// 返回复数 Z 的虚部值
float Getimag( complex Z );

// 以 sum 返回两个复数 z1, z2 的和 
void add( complex z1, complex z2, complex  &sum );

// -----基本操作的实现
void add( complex z1, complex z2, complex  &sum ) {
 // 以 sum 返回两个复数 z1, z2 的和
  sum.e1 = z1.e1 + z2.e1;
  sum.e2 = z1.e2 + z2.e2;
}

  

算法--求解特定问题的有限的操作步骤

算法的5个特性:

有限性:不能无限制的操作下去,不能死循环

确定性:每一步必须有明确含义,不能有歧义

可行性:每一步利用现有技术是可以实现的

输入:0个或多个输入

输出:1个或多个输出

算法的设计要求:

正确性

健壮性

可读性

效率和低存储量需求

效率—算法的执行时间

存储量—算法执行过程中间所需要的最大存储空间

度量方式

从算法中选取一种对于所研究的问题来说是基本操作的原操作,以该基本操作重复执行的次数作为算法的时间量度。

T(n)=O(f(n))  

随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐近时间复杂度,简称时间复杂度。

原操作执行次数和包含它的语句的频度相同。语句的频度指的是该语句重复执行的次数。  

O(1)    —常量阶

O( n )   —线性阶

O( n 2)  —平方阶

O(log n ) —对数阶

O(2n)  —指数阶

   多项式阶( O( n k) ),不希望用指数阶

算法的存储空间需求:

空间复杂度可以作为算法所需存储空间的量度

S(n)=O(f(n))

若额外空间相对于输入数据量来说是常数,则称此算法为原地工作。

如果所占空间量依赖于特定的输入,则除特别指明外,均按最坏情况来分析。