数据结构与算法:一、概论

数据结构是什么,它与数据库有什么不同?
数据结构指数据的组织方式,着重于数据之间的相互关系。数据库指一定规则存储在一起的数据集合,向外提供查询、插入、更新、删除等服务,着重于数据的存储与管理。数据结构通常与内存有关,数据库通常与硬盘有关。
数据结构与算法是一门研究非数值计算程序设计问题中计算机的操作对象以及它们之间的关系和操作等的学科。
主要研究
数据元素之间固有的逻辑关系——数据逻辑结构;
数据元素及关系在计算机内的表示——数据存储结构;
对数据结构的操作——算法。
基本术语
数据         数据元素             数据对象            数据结构
数据:是所有能被输入到计算机中,且能被计算机处理的符号(数字、字符等)的集合,它是计算机操作对象的总称。
是计算机处理的信息的某种特定的符号表示形式
数据的集合表示:数据={x|x是计算机操作的对象};
数据元素:数据结构中讨论的"基本单位";数据整体中相对独立的单位。
两类数据元素:
不可分割的“原子”型数据元素:整数"5",字符 "N" 等
多个数据项构成的数据元素,数据项是数据不可分割的最小标识单位。
数据对象:性质相同的数据元素的集合,是数据的一个子集。
 例如:
 整数数据对象集合:N={0,±1,±2,…},
 字母字符数据对象集合:C={‘A’,‘B’,…,‘Z’}。
数据结构
定义:是相互之间存在一种或多种特定关系的数据元素的集合。
特点:数据元素集合相同,而其上的关系不同,则构成的数据结构不同。
内容:
数据的逻辑结构
数据的存储结构
数据的操作
数据结构的形式定义
数据结构是一个二元组 DS = ( D,R ) 其中:D是数据元素的有限集,R是D上关系的有限集。
关系的表示:
序偶:有序对。例如:<班主任,班长1>
前驱:序偶中第一元素为第二元素的前驱
后继:序偶中第二元素为第一元素的后继

数据的逻辑结构:
对数据元素之间存在的逻辑关系的描述,它可以用一个数据元素的集合和定义在此集合上的若干关系表示。数据的逻辑结构可看作是从具体问题抽象出来的数学模型

数据的存储结构:
数据元素及其关系在计算机内的表示。
逻辑结构可以映射为以下 四种存储结构
  1、顺序存储结构:把逻辑上相邻的数据元素存储在物理位置也相邻的存储单元中,借助元素在存储器中的相对位置来表示数据元素  之间的逻辑关系。
  2、链式存储结构:借助指针表达数据元素间的逻辑关系。不要求逻辑上相邻的数据元素在物理位置上也相邻。
  3、索引存储结构:在存储数据元素的同时,还建立附加的索引表。通过索引表,可以找到存储数据元素的节点。
  4、散列存储结构:根据散列函数和处理冲突的方法确定数据元素的存储位置
学习每一种数据结构时都会从逻辑结构、存储结构和操作三方面入手
抽象数据类型
数据元素集合以及定义在该集合上的一组操作,简称为ADT(Abstract Data Type)。
“抽象”指与具体实现无关,仅考虑能做什么,而不考虑如何做。
形式描述
   ADT = ( D,R,P ) 其中:D 是数据对象,       R 是 D 上的关系集,    P 是 D 的基本操作集。
抽象数据类型重要特性 :
    数据抽象
用ADT描述程序处理的实体时,强调的是其本质的特征、其所能完成的功能以及它和外部用户的接口(即外界使用它的方法)。
    数据封装
将实体的外部特性和其内部实现细节分离,并且对外部用户隐藏其内部实现细节。
抽象数据类型的实现 :
面向对象——类
面向过程——结构体
举个例子 :
【例1-5】复数数据类型的抽象描述
分析:定义——实部+i虚部
                 实部和虚部的取值范围——实数
                 复数的操作——+、-、×、%
ADT复数的数据类型抽象 数据对象:
            D = {e1,e2 | 实数 } 数据关系:
            R1 = {<e1,e2> | e1是复数的实部,e2是复数的虚部 }
  用两个实数来表示复数,将复数定义为两个实数的有序对,并约定实部是前驱,虚部是后继。 


基本操作:
InitComplex( &Z, v1, v2 )
操作结果:构造复数Z,其实部和虚部分别被赋以参数v1和v2的值。
DestroyComplex( &Z) 操作结果:复数Z被销毁。
GetReal( Z, &realPart ) 操作结果:用 realPart 返回复数Z的实部值。
GetImag( Z, &ImagPart )
操作结果:用 ImagPart 返回复数Z的虚部值。
Add( z1,z2, &sum ) 操作结果:用sum返回两个复数z1,z2的和值。
End  ADT Complex
【例1-6】矩形数据类型抽象描述
分析:定义——长、宽
               长和宽的取值范围——实数
               矩形的操作——初始化(构造)矩形、计算矩形的
                                           周长和面积
ADT RECtangle is
 数据对象:D = {e1,e2 | 实数 } 数据关系:R1 = {<e1,e2> | e1是长,e2是宽 }
    基本操作:
InitRectangle(r,len,width);
操作结果:初始化矩形长和宽
Circumference(r);
操作结果:计算矩形周长
Area( r );
操作结果:计算矩形面积

算法:
算法就是求解问题的一系列步骤的集合。通常把具体存储结构上的操作实现步骤或过程称为算法
算法的特性(性质)
  1、有穷性: 对于任意一组合法的输入值,在执行有穷步骤之后一定能结束。
  2、确定性:每条指令必须有确切的含义,不能有二义性。
  3、可行性:算法中描述的操作都是用已经实现的基本运算组成。
输入:可以有0、1、或多个输入量。
输出:它是一组与"输入"有确定关系的量值,是算法进行信息加工后得到的结果,这种确定关系即为算法的功能。

举个例子:

void exam1()
 {
       n=2;
      while (n%2==0)   
             n=n+2;
      cout<<n<<endl;
 }                                               

void exam2()
 {
      y=0;
      x=5/y;
      cout<<x<<‘,’<<y<<endl;
 }

结果:(1)算法是一个死循环,违反了算法的有穷性特征。(2)算法包含除零错误,违反了算法的可行性特征

算法的设计准则:
  1、正确性
除了应该满足算法说明中写明的“功能”之外,应对各组典型的带有苛刻条件的输入数据得出正确的结果 。
  2、健壮性
算法应对非法输入的数据作出恰当反映或进行相应处理,一般情况下,应向调用它的函数返回一个表示错误或错误性质的值。
  3、可读性
易于理解、实现和调试。
  4、高效性
执行时间短(时间效率)、占用存储空间少(空间效率)
时间复杂度:
一般用算法中语句被执行的次数来表示算法的时间效率(算法的时间复杂度)。

【例1-8】分析下面程序段的时间复杂度。
                  (1) int i,sum=0;
                  (2) for(i=0;i<n;i++)
                  (3)  sum=sum+i;
                  (4) return sum;
         T(n)=2n+3,且T(n)是n数量级的。

渐进时间复杂度:忽略次要语句的执行次数,只对重要的语句(原操作)和执行最频繁的语句进行计数,同时对计算结果只取其最高次幂,且略去系数不写。
渐近时间复杂度常简称为时间复杂度,用大O表示。
                  T(n)=2n+3=O(n)
也就是只求出T(n)的最高阶,忽略其低阶项和常系数,这样既可简化T(n)的计算,又能比较客观地反映出当n很大时,算法的时间性能。
      例如,T(n)=3n2-5n+10000=O(n2)
 一个没有循环的算法的基本运算次数与问题规模n无关,记作O(1),也称作常数阶。
 一个只有一重循环的算法的基本运算次数与问题规模n的增长呈线性增大关系,记作O(n),也称线性阶。
其余常用的还有平方阶O(n2)、立方阶O(n3)、对数阶O(log2n)、指数阶O(2n)等。

各种不同数量级对应的值存在着如下关系:
O(1)<O(log2n)<O(n)<O(n*log2n)<O(n2)<O(n3)<O(2n)<O(n!)       

例子:                                                                                                                                                                       

int fun(int n)
  {
       int i,j,k,s;
       s=0;
       for (i=0;i<=n;i++)          
           for (j=0;j<=n;j++)   
                for (k=0;k<=n;k++)    
                     s++;
      return(s);
  }              该算法的基本操作是语句s++,其频度:            T(n)=O(n3)   则该算法的时间复杂度为O(n3)。

总结:    数据结构(逻辑结构、存储结构)
              抽象数据类型(数据与操作)
              算法的时间效率(时间复杂度)

扫描二维码关注公众号,回复: 3559721 查看本文章

                     

猜你喜欢

转载自blog.csdn.net/zxcvb12zxcvb12/article/details/79019483