数据结构和算法教程

目录

1.1数据结构的研究内容

1.2基本概念和术语

1.2.1数据,数据元素,数据项,数据对象

1.2.2数据结构(Data Structure)

1.2.3数据类型和抽象数据类型

1.3抽象数据类型的表示与实现

1.4算法和算法分析

算法时间复杂度的渐进表示法

渐进空间复杂度


1.1数据结构的研究内容

        通常,用计算机解决一个问题的步骤:具体问题抽象为数学模型(实质):分析问题;提取操作对象,找出操作对象之间的关系;用数学语言描述-》称为数据结构。设计算法。编程,调试,运行。

        早期,计算机主要用于数值计算。随着计算机应用领域的扩展,计算机被越来越多地用于非数值计算。

例如1 学生学籍管理系统

 操作对象:每位学生的信息(学号,姓名,性别,籍贯,专业....)

操作算法:查询,插入,修改,删除等。

操作对象之间的关系:线性关系        数据结构:线性数据结构,线性表。

类似的还有图书管理系统,人事管理系统,仓库管理系统,通讯录

操作对象:若干行数据记录

操作算法:查询,插入,修改,删除等

操作对象之间的关系:线性表

数据结构:线性数据结构

 例如2        人际对弈问题

人输入棋子:计算机进行运算推算出机器人下一步的棋局。之所以能对弈:策略已经输入计算机,可以根据当前棋局来预测棋局的发展趋势,甚至最后结果

计算机的操作对象:各种棋局状态,即描述棋盘的格局信息

计算机的算法:走棋,即选择一种策略使棋局状态发生变化(由一个格局派生出另一个格局)

  •  文件系统的系统结构图

磁盘根目录下有很多子目录及文件,每个子目录里又可以包含子目录及文件,但每个子目录只有一个父目录,依次类推

 综上所述

  • 这些问题的共性都是无法用数学的公式或方程来描述,是一些“非数值计算”的程序设计问题
  • 描述非数值计算问题的数学类型不是数学方程,而是诸如表,树和图之类的具有逻辑关系的数据
  • 数据结构是一门研究非数值计算的程序设计中计算机的操作对象以及,他们之间的关系和操作的学科

1.2基本概念和术语

1.2.1数据,数据元素,数据项,数据对象

数据(data)        数据元素(data element)     

数据项(data item)        数据对象(data object)

 1.数据(Data)

  •         是能够输入计算机且能被计算机处理的各种符号的集合
    • 信息的载体
    • 是对客观事物符号化的表示
    • 能够被计算机识别,存储加工
  • 包括:
    • 数值型的数据:整数,实数等;
    • 非数值型的数据:文字,图像,图形,声音等

2.数据元素(Data Element)

  • 数据元素
    • 是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理
    • 也简称为元素,或称为记录,结点或顶点。
    • 一个数据元素可由若干个数据项组成(Data Item)

3.数据项

  • 数据项
    • 构成数据元素的不可分割的最小单位
  • 数据,数据元素,数据项三者之间的关系:
    • 数据>数据元素>数据项
      • 例如:学生表>个人记录>学号,姓名.....

4.数据对象

  • 数据对象
    • 是性质相同是数据元素的集合,十数据的一个子集
  • 例如:
    • 整数数据对象是集合N={0,1,2,3.....};
    • 字母字符数据对象是集合C={‘A’,'B',.....'Z'}
    • 学籍表也可以看做一个数据对象
    • 数据元素-----组成数据的基本单位
      • 与数据的关系:是集合的个体
    • 数据对象----性质相同的数据元素的集合
      • 与数据的关系是:集合的子集

1.2.2数据结构(Data Structure)

  • 数据结构
    • 数据元素不是孤立存在的,他们之间存在着某种关系,数据元素相互之间的关系称为结构(Structure)
    • 是指相互之间存在一种或多种特定关系的数据元素的集合
    • 或者说,数据结构是带结构的数据元素的集合
  • 数据结构包括以下三个方面的内容
  1. 数据元素之间的逻辑关系,也称为逻辑结构
  2. 数据元素及其关系在计算机内存中的表示(又称为影像),称为数据的物理结构或数据的存储结构
  3. 数据的运算和实现,即对数据元素可以施加的操作以及这些操作在相应的存储结构上的实现
  • 逻辑结构
    • 描述数据元素之间的逻辑关系
    • 与数据的存储无关,独立于计算机
    • 是从具体问题抽象出来的数学模型
  • 物理结构(存储结构)
    • 数据元素及其关系在计算机存储器中的结构(存储方式)
    • 是数据结构在计算机中的表示
  • 逻辑结构与存储结构的关系:
    • 存储结构是逻辑结构的映像与元素本身的映象
    • 逻辑结构是数据结构的抽象,存储结构是数据结构的实现
    • 两者综合起来建立了数据元素之间的结构关系
  • 逻辑结构的种类
    • 划分方法一
    • (1)线性结构:有且仅有一个开始和终端结点,并且所有结点都最多只有一个直接前趋和一个直接后继
      • 例如:线性表,栈,队列,串
    • (2)非线性结构:一个结点可能有多个直接前趋和直接后继
      • 例如:树,图
    • 划分方法二——四类基本逻辑结构
    • (1)集合结构:结构中数据元素之间除了同属于一个集合的关系外,无任何其他关系
    • (2)线性结构:结构中数据元素之间存在着一对一的线性关系
    • (3)树形结构:结构中数据元素之间存在着一对多的层次关系
    • (4)图状结构网状结构:结构中的数据元素之间存在着多对多的任意关系
  • 四种基本的存储结构
    • 顺序存储结构
      • 用一组连续的存储单元依次存储数据元素,数据元素之间的逻辑关系由元素的存储位置来表示
      • C语言中用数组实现顺序存储结构
    • 链式存储结构
      • 用一组任意的存储单元存储数据元素,数据元素之间的逻辑关系用指针来表示
      • C语言中用指针(地址)来实现链式存储结构
    • 索引存储结构
      • 在存储结点信息的同时,还建立附加的索引表
      • 索引表中的每一项称为一个索引项
      • 索引项的一般形式是(关键字,地址)
      • 关键字是能唯一标识一个结点的那些数据项
      • 若每个结点在索引表中都有一个索引项,则该索引表称之为稠密索引(Dense Index)若一组结点在索引表中只对应一个索引项,则该索引表称为稀疏索引(Sparse Index)
    • 散列存储结构
      • 根据结点的关键字直接计算出该结点的存储地址

1.2.3数据类型和抽象数据类型

  • 在使用高级程序设计语言编写程序时,必须对程序中出现的每个变量,常量或表达式,明确说明它们所属的数据类型
    • 例如:C语言中:
      • 提供int,char,float,double等基本数据类型
      • 数组,结构,共用体,枚举等构造数据类型
      • 还有指针,空(void)类型
      • 用户也可以用typedef 自己定义数据类型
  • 一些最基本数据结构可以用数据类型来实现,如:数组,字符串等;
  • 而另一些常用的数据结构,如:栈,队列,树,图等,不能直接用数据结构类型来表示
  • 高级语言中的数据类型明显地或隐含地规定了在程序执行器件变量表达的所有可能的取值范围,以及在这些数值范围上所允许进行的操作
    • 例如:C语言中定义变量i为int 类型,就是表示i是[-min,max]范围的整数,在这个整数集上可以进行+,-。,/,%等操作
      • 数据类型的作用:1.约束变量或常量的取值范围2.约束变量或常量的操作
  • 数据类型(Data Type)
    • 定义:数据类型是一组性质相同的值的集合以及定义于这个值集合上的一组操作的总称
    • 数据类型=值的集合+值集合上的一组操作
  • 抽象数据类型(Abstract Data Tpye,ADT)
  • 是指一个数学模型以及定义在此数学模型上的一组操作
    • 由用户定义,从问题抽象出数据模型(逻辑结构)
    • 还包括定义在数据模型上的一组抽象运算(相关操作)
    • 不考虑计算机内的具体存储结构与运算的具体实现算法
  • 抽象数据类型的形式定义
    • 抽象数据类型可用(D S P)三元组表示
    • 其中:D是数据对象   S是D上关系集     P是对D的基本操作集
  • 一个抽象数据类型的定义格式如下:

ADT  抽象数据类型名{

        数据对象:<数据对象的定义>

        数据关系:<数据关系的定义>

        基本操作:<基本操作的定义>

}ADT 抽象数据类型名

其中:

  • 数据对象,数据关系的定义用伪代码描述
  • 基本操作的定义格式为:
    • 基本操作名(参数表)
    • 初始条件:(初始条件描述)
    • 操作结果:(操作结果描述)
  • 基本操作定义格式说明:
    • 参数表:
      • 赋值参数 只为操作提供输入值
      • 引用参数 以&打头,除可提供输入值,还将返回操作结果
    • 初始条件:描述操作执行之前数据结构和参数应满足的条件,若不满足则操作失败,并返回相应出错信息。若初始条件为空,则省略之
    • 操作结果:说明操作正常完成之后,数据结构的变化状况和应返回的结果

 

1.3抽象数据类型的表示与实现

  • 抽象数据类型可用通过固有的数据类型(如整型,实型,字符型)来表示和实现
    • 即利用处理器中已经存在的数据类型来说明新的结构,用已经实现的操作作为新的操作

1.4算法和算法分析

  • 算法的定义
    • 对特定问题求解和步骤的一种描述,他是指令的有限序列,其中每个指令表示一个或者多个操作:简而言之,算法就是解决问题的方法和步骤
  • 算法的描述
    • 自然语言:英语,中文
    • 流程图:传统流程图,NS流程图
    • 伪代码:类语言:类c语言
    • 程序代码:C语言程序,JAVA语言程序
  • 算法与程序
    • 算法是解决问题的一种或者一个过程,考虑如何将输入转换成输出,一个问题可以有多种算法
    • 程序是用某种程序设计语言对算法的具体实现
      • 程序=数据结构+算法
      • 数据结构通过算法实现操作
      • 算法根据数据结构设计程序
  • 算法特性:一个算法必须具备以下五个重要特性
    • 有穷性:一个算法必须总是在执行有穷步之后结束,且每一步都在有穷时间内完成
    • 确定性:算法中的每一条指令必须有确切的含义,没有二义性,在任何条件下,只有唯一的一条执行路径,即对于相同的输入只能得到相同的输出
    • 可行性:算法是可执行的,算法描述的操作可以通过已经实现的基本操作执行有限次来实现
    • 输入:一个算法有零个或者多个输入
    • 输出:一个算法有一个或者多个输入
  • 算法设计的要求
  • 正确性(Correctness):算法满足问题要求,能正确解决问题算法转化为程序后要注意:
  1. 程序中不含语法错误
  2. 程序对于1组输入数据能够得出满足要求的结果
  3. 程序对于精心选择的,典型,苛刻且带有刁难性的机组输入数据能够得出满足要求的结果
  4. 程序对于一切合法的输入数据都能够得出满足要求的结果     
  • 可读性(Readability)
  1. 算法主要是为了人的阅读和交流,其次才是为了计算机执行,因此算法应该易于人们理解
  2. 另一方面,晦涩难懂的算法易于隐藏较多错误而难以调试
  • 健壮性(Robustness)
  1. 指当输入非法数据时,算法恰当的做出反应或者进行相应的处理,而不是产生莫名其妙的输出结果
  2. 处理出错的方法,不应该是中断程序的执行,而是应返回一个表示错误或错误性质的值,以便在更高的抽象层次上进行处理
  • 高效性(Efficiency)
  1. 要求花费尽量少的时间和尽量低的存储要求

 算法效率以下两个方面来考虑:

  1. 时间效率:指的是算法所耗费的时间;
  2. 空间效率:指的是算法执行过程中所耗费的存储空间。
  3. 时间效率和空间效率有时候是矛盾的
  • 算法时间效率的度量
    • 算法时间效率可以用依据该算法编制的程序在计算机上执行所消耗的时间来度量
    • 两种度量方法
      • 事后统计
        • 将算法实现,测算其时间和空间开销
        • 缺点:编写程序实现算法将花费较多时间和精力:所得实验结果依赖于计算机的软硬件等环境因素,掩盖算法本身的优劣
      • 事前分析
        • 对算法所消耗资源的一种估算方法
      • 事前分析方法:
        • 一个算法的运行时间是指一个算法在计算机上运行所耗费的时间大致可以等于计算机执行一种简单的操作(如赋值,比较,移动等)所需的时间与算法中进行的简单操作次数乘积
        • 算法运行时间=一个简单操作所需的时间*简单那操作次数
        • 也即算法中每条语句的执行时间之和
        • 算法运行时间=\sum每条语句执行次数*该语句执行一次所需要的时间
        • 算法运行时间=\sum每条语句频度*该语句执行一次所需的时间

 例如:两个n*n矩阵相乘的算法可描述为:

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次
}

 我们把算法所耗费的时间定义为该算法中每条语句的频度之和,则上述算法的时间消耗T(n)

为:T(n)=2n^3+3n^2+2n+1;这是一个关于n的函数

算法时间复杂度的渐进表示法

  • 为了便于比较不同算法的时间效率,我们仅比较它们的数量级 
    • 例如:两个不同的算法,时间消耗分别是
      • T1(n)=10n^2        T2(n)=5n^3
      • 数量级越大越不好
  • 若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数.记作T(n)=O(f(n)).称O(f(n))为算法的渐进时间复杂度(O是数量级的符号),简称时间复杂度

对于求解矩阵相乘问题,算法耗费时间:

        T(n)=2n^3+3n^2+2n+1

n \to ∞时候,T(n)/n^3\rightarrow2,这表示n充分大时,T(n)与n^3是同阶或者同数量级,引入大"O"记号,则T(n)可记为:T(n)=O(n^3)

一般情况下,不必计算所有操作的执行次数,而只考虑算法中基本操作执行的次数,它是问题规模n的某个函数,用T(n)表示。

        算法中基本语句重复执行的次数问题规模n的某个函数f(n) 算法的时间度量记作:

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

        它表示随着n的增大,算法执行的时间的增长率和f(n)的增长率相同,称为渐进时间复杂度。

基本语句: 

  •  算法中重复执行次数和算法的执行时间成正比的语句
  • 对算法运行时间的贡献最大
  • 执行次数最多

问题规模:

  • n越大算法的执行时间越长
  • 排序:n为记录数
  • 矩阵:n为矩阵的阶数
  • 多项式:n为多项式的项数
  • 集合:n为元素的集合
  • 树:n为树的结点个数
  • 图:n为图的顶点树或边数

分析算法时间复杂度的基本方法:

 

 忽略所有低次幂项最高次幂系数,体现出增长率的含义

1.找出语句频度最大的那条语句作为基本语句

2.计算基本语句的频度得到问题规模n的某个函数f(n)

3.取其数量级用符号“O”表示

时间复杂度是由嵌套最深层语句的频度决定的

例题:

i=1;

while(i<=n)

        i=i*2;

所以时间复杂度是O(log2  n)

 

 请注意:有的情况下,算法中基本操作重复执行的次数还随问题的输入数据集不同而不同

例如:顺序查找,在数组a[i]中查找值等于e的元素,返回其所在位置

for(i=0;i<n;i++)
    if(a[i]==e)return i+1;//找到,则返回第几个元素
    return 0;
  • 最好情况:1次
  • 最坏情况:n次
  • 平均·时间复杂度为:O(n)
  • 算法时间复杂度
  • 最坏时间复杂度指在最坏情况下,算法的时间复杂度
  • 平均时间复杂度:值在所有可能输入实例在等概率出现的情况下,算法的期望运行时间
  • 最好时间复杂度:指在最好情况下,算法的时间复杂度
    • 一般总是考虑在最坏情况下的时间复杂度,以保证算法的运行时间不会比他更长

 对于复杂的算法,可将它分成几个容易估算的部分,然后利用大O的加法法则和乘法法则,计算算法的时间复杂度:

 算法时间效率的比较

  • 当n取得很大时,指数时间算法和多项式时间算法在所需时间上非常悬殊

 

 时间复杂度T(n)按数量级递增顺序为:

渐进空间复杂度

  • 空间复杂度:算法所需存储空间的度量,记作:S(n)=O(f(n))其中n为问题的规模(或大小)
  • 算法要占用的空间
    • 算法本身要占据的空间,输入/输出,指令,常数,变量等
    • 算法要使用辅助空间

 例题:将一维数组a中的n个数逆序存放到原数组中

算法一
for(i=0;i<n/2;i++)
{
    t=a[i];
    a[i]=a[n-i-1];
    a[n-i-1]=t;
}//S(n)=O(1)称为常数:原地工作
算法二
for(i=0;i<n;i++)
{
    b[i]=a[n-i-1];
}
for(i=0;i<n;i++)
{
    a[i]=b[i];
}
//S(n)=O(n)

  • 14
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值