2024.07.15:数据结构的基本概念学习笔记
1.1 前言
1.1.1 这门课程是讲什么的?
程序 == 数据结构 + 算法 (程序的本质)
1.1.2 这门课重要吗?
数据结构在计算机学科中的地位
- 数据结构是计算机软件相关专业的(专业基础课)
- 在教学计划中的地位:核心、承上启下的课程
- 数据结构是介于数学、计算机硬件和计算机软件三者之间的一门(核心课程)
- 类似于武术中的“练功”科目:“练武不练功,到头一场空”
- 考研:必考专业课,四门专业课(150分)
- 找工作:面试最主要考核的内容
1.1.3 这门课好学吗?
- 概念性强
- 算法灵活
- 逻辑性强
1.1.4 怎么才能学好这门课?
- 勤于思考
- 多做练习
- 多上机
- 善于寻求帮助
- 不怕困难,不放弃
1.2 数据结构研究
1.2.1 通常用计算机解题的问题步骤
- 分析问题
- 提取操作对象
- 找出操作对象之间的关系
- 用数学语言描述(数据结构)
- 设计算法
- 编程
- 调试
- 运行
1.3 基本概念和术语
1.3.1 数据、数据元素、数据项和数据对象
- 数据(数值型数据、非数值型数据):能输入计算机且能被计算机处理的各种符号的集合
- 数据元素(数据的基本单位):在计算机程序中通常作为一个整体进行考虑和处理,数据元素也简称元素,或称为(记录)(结点)(顶点)
- 数据项:构成数据元素的不可分割的最小单位
数据>数据元素>数据项
- 数据对象:性质相同的数据元素的集合,是数据的一个子集
- 数据元素是组成数据的基本单位
- 数据元素与数据的关系:是集合的个体
- 数据对象是性质相同的数据元素的集合
- 数据对象与数据的关系:是集合的子集
1.3.2 数据结构(线性结构、非线性结构)(四类基本逻辑结构)
- 数据元素不是孤立存在的,它们之间存在着某种关系,数据元素相互之间的关系称为结构
- 是指相互之间存在的一种或多种特定关系的数据元素的集合
- 或者说,数据结构是带结构的数据元素的集合
(1)数据结构包括以下三个方面的内容:逻辑结构(逻辑关系)、存储结构(物理结构)、数据的运算和实现
- 数据元素之间的逻辑关系,也称为逻辑结构
- 数据元素及其关系在计算机内存中的表示(映像),称为数据的物理结构或者数据的存储结构
- 数据的运算和实现,即对数据元素可以施加的操作以及这些操作在相应的存储结构上的实现
逻辑结构(逻辑关系)
- 描述数据元素之间的逻辑关系
- 与数据的存储无关,独立于计算机
- 是从具体问题抽象出来的数学模型
物理结构(存储结构)
- 数据元素及其关系在计算机存储器中的结构(存储方式)
- 是数据结构在计算机中的表示
逻辑结构与存储结构的关系
- 存储结构是逻辑关系的映像与元素本身的映像
- 逻辑结构是数据结构的抽象
- 存储结构是数据结构的实现
- 两者综合起来建立了数据元素之间的结构关系
(2)逻辑结构的划分结构1:线性结构、非线性结构
- 线性结构
- 非线性结构
(3)逻辑结构的划分结构2:四类基本逻辑结构
- 集合结构
- 线性结构
- 树形结构
- 图状结构/网状结构
(4)存储结构的种类:四种基本的存储结构
- 顺序存储结构
- 链式存储结构
- 索引存储结构
- 散列存储结构
1.3.3 数据类型和抽象数据类型
在使用高级程序设计语言编写程序时,必须对程序中出现的每个变量、常量或表达式,明确说明它们所属的数据类型
- 一些最基本的数据结构可以用数据类型来实现,如数组、字符串等
- 而另一些常用的数据结构,如栈、队列、树、图等,不能直接用数据类型来表示
(1)数据类型的作用
- 约束变量或常量的取值范围
- 约束变量或常量的操作
(2)数据类型
- 数据类型时一组性质相同的值的集合以及定义于这个值集合上的一组操作的总称。
- 数据类型==值的集合+值集合上的一组操作
(3)抽象数据类型
抽象数据类型是指一个数学模型以及定义在此数学模型上的一组操作
- 由用户定义,从问题抽象出的数据类型(逻辑机构)
- 还包括定义在数据模型上的一组抽象运算(相关操作)
- 注意:抽象数据类型不考虑计算机内的具体存储结构与运算的具体实现算法
抽象数据类型的形式定义
抽象数据类型可用(D,S,P)三元组表示:D是数据对象、S是D上的关系集、P是对D的基本操作集
抽象数据类型(ADT)定义举例
1.3.4 概念小结
1.4 抽象数据类型的表示与实现
抽象数据类型可以通过固有的数据类型来表示和实现
- 即利用处理器中已存在的数据类型来说明新的结构,用已经实现的操作来组合新的操作
- 本门课程使用类C语言(介于伪码和C语言之间)
1.5 算法与算法分析
1.5.1 算法的定义
- 对特定问题求解方法和步骤的一种描述,它是指令的有限序列。其中,每个指令表示一个或多个操作。
- 算法就是解决问题的方法和步骤
1.5.2 算法的描述
- 自然语言:英语、汉语
- 流程图:传统流程图、NS流程图(盒图)
- 伪代码:类语言(类C语言)
- 程序代码:C语言程序、JAVA语言程序
1.5.3 算法和程序
- 算法是解决问题的一种方法或一个过程,考虑如何将输入转换成输出,一个问题可以有多种算法
- 程序是用某种程序设计语言对算法的具体实现
1.5.4 算法的特性:有穷性、确定性、可行性、输入、输出
1.5.5 算法设计的要求:正确性、可读性、健壮性、高效性
1.5.6 算法的效率
时间效率和空间效率有时候是矛盾的
(1) 时间效率:指的是算法所耗费的时间
算法时间效率可以用依据该算法编址的程序在计算机上执行所消耗的时间来度量。
事后统计(不推荐)
- 将算法实现,测算其时间和空间开销
- 缺点:编写程序实现算法将花费较多的时间和精力;所得实验结果依赖于计算机的软硬件等环境因素,掩盖算法本身的优劣
事前分析(推荐)
对算法所消耗资源的一种估算方法
- 算法运行时间==一个简单操作所需的时间*简单操作次数
- 也就是算法中每条语句的执行时间之和
每条语句执行一次所需的时间,一般是随机器而异的。取决于机器的指令性能、速度以及编译的代码质量。是由机器本身软硬件环境决定的,它与算法无关。
所以,我们可假设执行每条语句所需的时间均为单位时间。此时对算法的运行时间的讨论就可转化为讨论该算法中所有语句的执行次数,即频度之和了。
- 为了方便比较不同算法的时间效率,我们仅比较它们的数量级。
- 若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的相同数量级函数。记作T(n)=O(f(n)),称O(f(n))为算法的渐进时间复杂度(O是数量级的符号),简称时间复杂度。
一般情况下,不必计算所有操作的执行次数,而只考虑算法中的基本操作执行的次数,它是问题规模n的某个函数,用T(n)表示
算法中重复执行次数和算法的执行时间成正比的语句,对算法运行时间的贡献最大,执行次数最大的语句
n越大,算法的执行时间越长
- 排序:n为记录数
- 矩阵:n为矩阵的阶数
- 多项式:n为多项式的项数
- 集合:n为元素个数
- 树:n为树的结点个数
- 图:n为图的定点数或边数
分析算法时间复杂度的基本方法(渐进时间复杂度)
- 找出语句频度最大的那条语句作为基本语句
时间复杂度是由嵌套最深层语句的频度决定的,因此频度最大的语句,基本上就是嵌套层次最深的语句
- 计算基本语句的频度得到问题规模n的某个函数f(n)
- 取其数量级用符号”O“表示
注意:有的情况下,算法中的基本操作重复执行的次数还随问题的输入数据集不同而不同
算法时间复杂度
- 最坏时间复杂度:指在最坏情况下,算法的时间复杂度
我们一般考虑在最坏情况下的时间复杂度,以保证算法的运行时间不会比它更长
- 平均时间复杂度:指在所有输入实例在等概率出现的情况下,算法的期望运行时间
- 最好时间复杂度:指在最好情况下,算法的时间复杂度
对于复杂的算法,可以将它分成几个容易估算的部分,然后利用大O加法法则和乘法法则,计算算法的时间复杂度
算法时间效率的比较
当n取得很大时,指数时间算法和多项式时间算法在所需时间上非常悬殊
(2) 空间效率:指的是算法执行过程中所耗费的存储空间
渐进空间复杂度
空间复杂度:算法所需存储空间的度量,记作:S(n)=O(f(n)),其中n为问题的规模(或大小)
算法要占据的空间
- 算法本身要占据的空间,输入/输出,指令,常数,变量等
- 算法要使用的辅助空间